TIL #35 Django : Model method


🐶 中に入ると


Djangoを勉強していろいろな方法を知りました.基本的な方法は次のとおりです.
  • all()/values()
  • get()/filter()
  • create()/save()
  • 似たような要素の違いを見ていきましょう.
    注意:Django公式文書https://docs.djangoproject.com/en/3.1/ref/models/querysets영어문서 익숙해...ㅠ 전공을 바꿔도 벗어날수 없어

    I. all() & values()


    共通点は両方ともQuerySet形式で出力され、値()にパラメータが入力されていない場合はall()などのすべての値が出力されます.

    1. all()


    all()は현재 Queryset의 copy를 returnを表す.Querysetの形式、すなわちlistの外観で、QuerySetには各インスタンスが含まれており、出力後は以下のようになる.
    >>> from products.models import Category
    >>> Category.objects.all()
    <QuerySet [<Category: Category object (1)>, <Category: Category object (2)>, <Category: Category object (3)>, <Category: Category object (4)>, <Category: Category object (5)>, <Category: Category object (6)>, <Category: Category object (7)>]>
    str()メソッド追加例
    >>> from products.models import Menu
    >>> Menu.objects.all()
    <QuerySet [<Menu: 음료>, <Menu: 푸드>, <Menu: 상품>, <Menu: 카드>]>

    2. values()


    valuesの入力形式はvalues(*fields, **expressions)です.
    この方法はall()と同様にQuerySetを返し、all()とは異なりdictionaryに変換される.dictionary를 포함한 QuerySetの形態
    Returns a QuerySet that returns dictionaries, rather than model instances, when used as an iterable.
    文章はよく理解できないが,出力形式からall()との違いが分かる.
    >>> from products.models import Drink
    >>> Drink.objects.values()
    <QuerySet [{'id': 1, 'name': '아인슈페너', 'name_en': 'Einspanner', 'category_id': 1}, {'id': 2, 'name': '아메리카노', 'name_en': 'Americano', 'category_id': 1}, {'id': 3, 'name': '딸기라떼', 'name_en': 'Strawberry latte', 'category_id': 2}, {'id': 4, 'name': '달고나 라떼', 'name_en': 'Dalgona Latte', 'category_id': 2}, {'id': 5, 'name': '석류애플라임', 'name_en': 'Pomegranate Apple Lime', 'category_id': 3}]>
    >>> Drink.objects.values('id', 'name_en')
    <QuerySet [{'id': 1, 'name_en': 'Einspanner'}, {'id': 2, 'name_en': 'Americano'}, {'id': 3, 'name_en': 'Strawberry latte'}, {'id': 4, 'name_en': 'Dalgona Latte'}, {'id': 5, 'name_en': 'Pomegranate Apple Lime'}]>
    values()に何も入力しない場合、all()のように모든 데이터를 출력の下にdictionaryの形状があり、values()に*fields 와 특정 **expression 을 지정하여 출력を入力できます.

    +)はfilterと一緒に使用できます:filter(条件)。values()

    //1번
    >>> Drink.objects.filter(category_id=1)
    <QuerySet [<Drink: Drink object (1)>, <Drink: Drink object (2)>]>
    //2번
    >>> Drink.objects.filter(category_id=1).values()
    <QuerySet [{'id': 1, 'name': '아인슈페너', 'name_en': 'Einspanner', 'category_id': 1}, {'id': 2, 'name': '아메리카노', 'name_en': 'Americano', 'category_id': 1}]>
    //3번
    >>> Drink.objects.filter(category_id=1).values('id', 'name_en')
    <QuerySet [{'id': 1, 'name_en': 'Einspanner'}, {'id': 2, 'name_en': 'Americano'}]>
  • フィルタ、条件出力のみの場合
  • フィルタを条件として、値()により
  • を辞書形式で出力.

  • 条件は
  • filter、出力は
  • 、パラメータはname en()

    II. get() & filter()


    get()もfilter()もDjangoにおけるREADデータベースのデータの場合に用いる方法である.すなわち、clientでは、get()およびfilter()により、요청がプロセスを介して条件に合致するデータを出力する.

    1. get()


    get()メソッドは、条件を満たす단 하나의 데이터を出力する.このときの形式ではオブジェクト値のみが出力され,QuerySetではない.
    >>> Drink.objects.get(id=1)
    <Drink: Drink object (1)>

    1)このオブジェクトの特定のカラムの値を知りたい場合は?

    변수.attributeを使用して、変数に出力するオブジェクトを格納します.
    >>> drink=Drink.objects.get(id=1)
    >>> drink.name
    '아인슈페너'
    >>> drink.name_en
    'Einspanner'
    >>> drink.category_id
    1

    2)FKでのattributeの読み出し

    >>> drink.category_id.name
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
    AttributeError: 'int' object has no attribute 'name'
    FKで受信したcategory idのtypeはintなので、そうはできません
    >>> drink.category.name
    '에스프레소'
    後は_idと書かない!FKのFKは使用できません(直接接続されたFKのみ)

    2. filter()


    filter()は、その名の通り걸러서 출력하게 한다.であるため、listと同様にQuerySetの形式の不特定多数の数の値を出力することができる.
    >>> Drink.objects.filter(id=1)
    <QuerySet [<Drink: Drink object (1)>]>
    >>> Drink.objects.filter(category_id=3)
    <QuerySet [<Drink: Drink object (5)>, <Drink: Drink object (6)>]>
    항상 QuerySet의 형태로 출력한다.

    1)QuerySetはindex-1コマンドを認識できません!!


    リストでは逆数カウントは−1から始まるが,QuerySetは−1という概念を認識していない.

    関数strを追加する例

    def __str__(self):
    	return self.name #여기서 name 부분은 attribute
    
    >>> Menu.objects.filter(id=1)
    <QuerySet [<Menu: 음료>]>

    III. create() & save()


    2つのメソッドの新しい挿入値の意味は同じです.

    1. create()


    命令の形式は以下の通りです.create(**kwargs)createは새로운 object를 만듬과 동시에 저장の方法です.
    すなわち、テーブルに新しいデータ(insert)を追加する方法は、生成されたインスタンスを返す.
    class.objects.create(column명='넣을값')

    +)キー値を入力する必要があります。


    Django練習では、データを繰り返し追加して実行します.
    どうせProductクラスにはname/categor id/nameenという属性が固定されているので、createコマンドを入力する際にキー値を使う必要はなく、valueを順番に入力するだけでいいのでは?と思った.
    結論はだめだ.エラーが発生しました.
    >> Drink.objects.create('레몬에이드', 3, 'Lemon Ade')
    Traceback (most recent call last):
      File "<console>", line 1, in <module>
      File "/Users/생략/django/db/models/manager.py", line 85, in manager_method
        return getattr(self.get_queryset(), name)(*args, **kwargs)
    TypeError: create() takes 1 positional argument but 4 were given
    当初は公式文書でもcreateのパラメータで*kwargsの形態を受け入れるという説がありました.

    ? nullが設定されていない場合に値を入力せずに作成しますか?


    create時にattributeのnullのデフォルト値がNoであることを確認し、create時に値を入力する必要がなく入力...
    <Drink: Drink object (16)>
    >> Drink.objects.create(category_id=1, name_en='water')
    <Drink: Drink object (17)>
    ふん、これはちょっと聞かなければなりません.

    2. save()


    save()は、insertまたはUpdateの場合に用いられる方法である.主に단일 객체의 update 시에 많이 사용된다.

    1)挿入例


    create()メソッドを使用する場合:
    Drink.objects.create(name='물', category_id=1, name_en='water')
    ただし、save()で機能を同じにするには、次の操作を行います.
    p = Drink(name='물', category_id=1, name_en='water')
    p.save(force_insert=True)

    2)更新例-Django


    さっきnullが指定されていなかった場合、値を入力しないと保存されますか?試行時に直接保存した17番idを例に挙げます.
    >>> d = Drink.objects.get(id=17)
    >>> d.name
    ''
    >>> d.name='비타민워터'
    >>> d.save()
    >>> d.name
    '비타민워터'
  • 変数dにはpk 17個のインスタンスが格納されている.
  • 元pk 17号にはnameの値はありませんでした.したがって、出力は「」です.
  • d.nameは「ビタミン水」と宣言した.(nameは、元々Drink classに所属していたattributeです.)
  • d.save()で値を格納します.
  • は再びd.nameを入力し、前に宣言し保存した「ビタミン水」を出力した.
  • 3)更新例-データベース


    上記の例では、データベースにどのような変化があるかを説明しました.
    >>> a = Drink.objects.get(id=16)
    >>> a.name
    ''
    >>> a.name='수돗물'
    「水道水」が新たに発表されるまで、机の状態は変わらなかった.
    a.save()
    saveを瞬時にデータベースに適用します.

    では、データを更新するとき、updateとsave()のどちらがいいのでしょうか。🏃🏻‍♀️