[TIL.34]DjangoモデルAPI(データインポート-正参照、逆参照)
Queryset?
クエリー・セットとは、渡されたモデルのオブジェクトのリストです.データベースからデータの読み込み、フィルタリング、ソートなどができます.リストと構造は同じですが、Pythonの基本資料構造ではなく、読み書きのために資料型変換が必要です.クエリー・セットは、データベース内の複数のレコード(行)を表します.from .models import Book
Book.objects.all() # Book 모델(테이블)의 모든 데이터를 갖고와라!
<QuerySet [<Book: 책 제목1>, <Book: 책 제목2>]>
ここでobjectsはModel Managerです.データベースとDjangoモデル間のクエリー操作のインタフェース.この場合、objectsを使用して複数のデータを取得する関数を使用すると、返されるオブジェクトはQuerySetです.
マネージャの各モデル(クラス)には少なくとも1つあります.
Person.objectsとは、objectsというmanagerがPersonデータベースをQuerySetにすることを意味します.彼らにそのQuerySetでデータを検索させることができます.
CRUD
クエリー・セットを返さない方法
from .models import Book
Book.objects.all() # Book 모델(테이블)의 모든 데이터를 갖고와라!
<QuerySet [<Book: 책 제목1>, <Book: 책 제목2>]>
クエリー・セットを返さない方法
create()
.get()
1行のみインポートする場合に使用します.
Question.objects.get(pk=1)
pkが1の値
1つの値のみ取得
<オブジェクトを返す>
.update()
指定したフィールドの更新クエリーを実行し、一致するローの数を返します.
In : Category.objects.filter(name='탄산').update(name='콜드브루')
Out : 2 #총 업데이트된 row 개수
データ消去に使用します.
を選択して設定できます.
まず削除するRowオブジェクトを読み込み、使用します.
fb = Feedback.objects.get(pk=2)
fb.delete()
個々のオブジェクトに対して更新を実行するための挿入、更新を実行する方法.
In : category = Category.objects.get(id=2)
Out : <Category: Category object (2)>
In : category.name
Out : '브루드커피'
In : category.name = 'new name'
In : category.save()
In : category.name
Out : 'new name'
filterを使用して条件を満たすデータを検索し、Trueが返されない場合、falsereturn
In : Category.objects.filter(name='브루드커피').exists()
Out : True
クエリー・セットを返す方法
all()
すべてのテーブルデータを取得する方法
<クエリーセットに戻る>
filter, exclude()
-> .filter()
特定の条件を満たすRowのインポートに使用
2つ以上の値を取得することもできます
何の条件も持たないすべてと同じ
<クエリーセットに戻る>
values()
iterableとして使用すると、モデルインスタンスではなくdictionaryを含むクエリーセットが返されます.
values_list()
tupleを返します.
多対多関係の場合に使用します.
d1 = Drink.objects.get(id=1)
a1 = Allergy.objects.get(id=1)
#drink와 allergy는 다대다 관계이고, 중간 테이블(DrinkAllergy 테이블)을 거치지 않고 drink를 통해 allergy에 정보를 담을 수 있다.
d1.allergies.add(a1)
q = Question(question_text="What's new?", pub_date=timezone.now())
データがあるかどうか見てみましょう.
シェルでデータが入っているかどうかを一つ一つ検索してからビューに入れます!
電源を切ると内容が消えます(変数とか)
objectにしか使えないattributeがあるので、よく知っておきましょう.
Many to Many関係を設定するより良い理由は?
中間テーブルAllergyDrinkを作成し、AllergyとDrinkをFKに接続しますが、実際にデータの読み取りとインポートに問題はありません.しかし、なぜ関係を多対多に設定しなければならないのだろうか.
1)データを入れるときに中間表を通す必要がないので、簡単になりました.
2)データをインポートする場合は、最小のデータベースでインポートするのが望ましいが、MTM接続の場合は、中間テーブルを必要とせずにデータをインポートするプロセスが簡単になる.
詳細の表示
マルチペアマルチリレーションシップを追加する利点は、中間テーブルを必要とせず、いつでも簡単にデータを追加およびインポートできることです.
データのインポート(「」を参照) class Drink(models.Model):
korean_name = models.CharField(max_length=45)
english_name = models.CharField(max_length=45)
description = models.TextField()
category = models.ForeignKey('Category', on_delete=models.CASCADE)
allergies = models.ManyToManyField(Allergy, through = "AllergyDrink")
class Category(models.Model):
name = models.CharField(max_length=45)
menu = models.ForeignKey('Menu', on_delete=models.CASCADE)
class Allergy(models.Model):
name = models.CharField(max_length=45)
class AllergyDrink(models.Model):
allergy = models.ForeignKey('Allergy',on_delete=models.CASCADE)
drink = models.ForeignKey('Drink',on_delete=models.CASCADE)
正参照の場合。
1)Drinkにより、driveが参照するcategoryを容易に知ることができる.(Drink -> Category)In [42]: d1 = Drink.objects.get(id=1)
In [43]: d1.category.name
Out[43]: '콜드 브루 커피'
# 또는 이렇게
In [47]: Drink.objects.get(id=1).category.name
Out[47]: '콜드 브루 커피'
2)dinkによるアレルゲン導入(++多対多関係)# 1개의 알러지만 가지고 있는 경우
In [2]: d1 = Drink.objects.get(id=1)
In [4]: d1.allergies.get()
Out[4]: <Allergy: Allergy object (2)>
In [5]: d1.allergies.values()
Out[5]: <QuerySet [{'id': 2, 'name': '우유'}]>
In [6]: d1.allergies.get().name
Out[6]: '우유'
# 2개 이상의 알러지를 가지고 있는 row
In [7]: d10 = Drink.objects.get(id=10)
In [8]: d10.allergies.values()
Out[8]: <QuerySet [{'id': 1, 'name': '대두'}, {'id': 2, 'name': '우유'}]>
In [9]: a = d10.allergies.values()
In [10]: for i in a:
...: print(i)
...:
{'id': 1, 'name': '대두'}
{'id': 2, 'name': '우유'}
In [11]: for i in a:
...: print(i['name'])
...:
...:
대두
우유
# 또 다른 방법
In [42]: Drink.objects.get(id=1).allergies
Out[42]: <django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager at 0x7f8b6ec95190>
In [43]: Drink.objects.get(id=1).allergies.get()
Out[43]: <Allergy: Allergy object (2)>
In [44]: Drink.objects.get(id=1).allergies.get().name
Out[44]: '우유'
逆参照の場合
related nameが設定されていない場合は、setが貼り付けられ、逆参照データであることを示します.
✔¥逆参照系
Fkのクラスが指定されていません.つまり、pkが存在するテーブル!
1)Category逆参照DrinkのインポートIn [11]: Category.objects.get(id=1).drink_set
Out[11]: <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager at 0x7fe9e0c6dc90>
In [12]: Category.objects.get(id=1).drink_set.all()
Out[12]: <QuerySet [<Drink: Drink object (1)>, <Drink: Drink object (2)>, <Drink: Drink object (7)>, <Drink: Drink object (8)>, <Drink: Drink object (11)>, <Drink: Drink object (12)>]>
In [13]: c = Category.objects.get(id=1).drink_set.all()
In [16]: for ca in c:
...: print(ca.korean_name)
...:
...:
...:
나이트로 바닐라 크림
미드나잇 베르가못 콜드 브루
벨젯 다크 모카 나이트로
프렌치 애플 타르트 나이트로
프렌치 애플 타르트 나이트로
카푸치노
2)アレルギーによる飲み物の入手方法(Driink->Allergy:もとはこう引用した関係)(++multi to multi関係)In [26]: Allergy.objects.get(id=2).drink_set.values()
Out[26]: <QuerySet [{'id': 1, 'korean_name': '나이트로 바닐라 크림', 'english_name': 'Nitro Vanilla Cream', 'description': '부드러운 목넘김의 나이트로 커피와 바닐라 크림의 매력을 한id': 2, 'korean_name': '미드나잇 베르가못 콜드 브루', 'english_name': '', 'description': '', 'category_id': 1}, {'id': 3, 'korean_name': '딸기 딜라이트 요거트 블렌디드', 'english_n'', 'category_id': 2}, {'id': 5, 'korean_name': '쿠키 블루베리 잼 머핀', 'english_name': '', 'description': '', 'category_id': 3}, {'id': 7, 'korean_name': '벨젯 다크 모카 나이트로'', 'description': '', 'category_id': 1}, {'id': 10, 'korean_name': '돌체 라떼', 'english_name': '', 'description': '', 'category_id': 3}]>
In [27]: b = Allergy.objects.get(id=2).drink_set.values()
In [28]: for bs in b:
...: print(bs)
...:
{'id': 1, 'korean_name': '나이트로 바닐라 크림', 'english_name': 'Nitro Vanilla Cream', 'description': '부드러운 목넘김의 나이트로 커피와 바닐라 크림의 매력을 한번에 느껴보세요!', 'category_id': 1}
{'id': 2, 'korean_name': '미드나잇 베르가못 콜드 브루', 'english_name': '', 'description': '', 'category_id': 1}
{'id': 3, 'korean_name': '딸기 딜라이트 요거트 블렌디드', 'english_name': '', 'description': '', 'category_id': 2}
{'id': 5, 'korean_name': '쿠키 블루베리 잼 머핀', 'english_name': '', 'description': '', 'category_id': 3}
{'id': 7, 'korean_name': '벨젯 다크 모카 나이트로', 'english_name': '', 'description': '', 'category_id': 1}
{'id': 10, 'korean_name': '돌체 라떼', 'english_name': '', 'description': '', 'category_id': 3}
In [29]: for bs in b:
...: print(bs['korean_name'])
...:
...:
나이트로 바닐라 크림
미드나잇 베르가못 콜드 브루
딸기 딜라이트 요거트 블렌디드
쿠키 블루베리 잼 머핀
벨젯 다크 모카 나이트로
돌체 라떼
all, get, values
class Drink(models.Model):
korean_name = models.CharField(max_length=45)
english_name = models.CharField(max_length=45)
description = models.TextField()
category = models.ForeignKey('Category', on_delete=models.CASCADE)
allergies = models.ManyToManyField(Allergy, through = "AllergyDrink")
class Category(models.Model):
name = models.CharField(max_length=45)
menu = models.ForeignKey('Menu', on_delete=models.CASCADE)
class Allergy(models.Model):
name = models.CharField(max_length=45)
class AllergyDrink(models.Model):
allergy = models.ForeignKey('Allergy',on_delete=models.CASCADE)
drink = models.ForeignKey('Drink',on_delete=models.CASCADE)
正参照の場合。
1)Drinkにより、driveが参照するcategoryを容易に知ることができる.(Drink -> Category)
In [42]: d1 = Drink.objects.get(id=1)
In [43]: d1.category.name
Out[43]: '콜드 브루 커피'
# 또는 이렇게
In [47]: Drink.objects.get(id=1).category.name
Out[47]: '콜드 브루 커피'
2)dinkによるアレルゲン導入(++多対多関係)# 1개의 알러지만 가지고 있는 경우
In [2]: d1 = Drink.objects.get(id=1)
In [4]: d1.allergies.get()
Out[4]: <Allergy: Allergy object (2)>
In [5]: d1.allergies.values()
Out[5]: <QuerySet [{'id': 2, 'name': '우유'}]>
In [6]: d1.allergies.get().name
Out[6]: '우유'
# 2개 이상의 알러지를 가지고 있는 row
In [7]: d10 = Drink.objects.get(id=10)
In [8]: d10.allergies.values()
Out[8]: <QuerySet [{'id': 1, 'name': '대두'}, {'id': 2, 'name': '우유'}]>
In [9]: a = d10.allergies.values()
In [10]: for i in a:
...: print(i)
...:
{'id': 1, 'name': '대두'}
{'id': 2, 'name': '우유'}
In [11]: for i in a:
...: print(i['name'])
...:
...:
대두
우유
# 또 다른 방법
In [42]: Drink.objects.get(id=1).allergies
Out[42]: <django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager at 0x7f8b6ec95190>
In [43]: Drink.objects.get(id=1).allergies.get()
Out[43]: <Allergy: Allergy object (2)>
In [44]: Drink.objects.get(id=1).allergies.get().name
Out[44]: '우유'
逆参照の場合
related nameが設定されていない場合は、setが貼り付けられ、逆参照データであることを示します.
✔¥逆参照系
Fkのクラスが指定されていません.つまり、pkが存在するテーブル!
1)Category逆参照Drinkのインポート
In [11]: Category.objects.get(id=1).drink_set
Out[11]: <django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager at 0x7fe9e0c6dc90>
In [12]: Category.objects.get(id=1).drink_set.all()
Out[12]: <QuerySet [<Drink: Drink object (1)>, <Drink: Drink object (2)>, <Drink: Drink object (7)>, <Drink: Drink object (8)>, <Drink: Drink object (11)>, <Drink: Drink object (12)>]>
In [13]: c = Category.objects.get(id=1).drink_set.all()
In [16]: for ca in c:
...: print(ca.korean_name)
...:
...:
...:
나이트로 바닐라 크림
미드나잇 베르가못 콜드 브루
벨젯 다크 모카 나이트로
프렌치 애플 타르트 나이트로
프렌치 애플 타르트 나이트로
카푸치노
2)アレルギーによる飲み物の入手方法(Driink->Allergy:もとはこう引用した関係)(++multi to multi関係)In [26]: Allergy.objects.get(id=2).drink_set.values()
Out[26]: <QuerySet [{'id': 1, 'korean_name': '나이트로 바닐라 크림', 'english_name': 'Nitro Vanilla Cream', 'description': '부드러운 목넘김의 나이트로 커피와 바닐라 크림의 매력을 한id': 2, 'korean_name': '미드나잇 베르가못 콜드 브루', 'english_name': '', 'description': '', 'category_id': 1}, {'id': 3, 'korean_name': '딸기 딜라이트 요거트 블렌디드', 'english_n'', 'category_id': 2}, {'id': 5, 'korean_name': '쿠키 블루베리 잼 머핀', 'english_name': '', 'description': '', 'category_id': 3}, {'id': 7, 'korean_name': '벨젯 다크 모카 나이트로'', 'description': '', 'category_id': 1}, {'id': 10, 'korean_name': '돌체 라떼', 'english_name': '', 'description': '', 'category_id': 3}]>
In [27]: b = Allergy.objects.get(id=2).drink_set.values()
In [28]: for bs in b:
...: print(bs)
...:
{'id': 1, 'korean_name': '나이트로 바닐라 크림', 'english_name': 'Nitro Vanilla Cream', 'description': '부드러운 목넘김의 나이트로 커피와 바닐라 크림의 매력을 한번에 느껴보세요!', 'category_id': 1}
{'id': 2, 'korean_name': '미드나잇 베르가못 콜드 브루', 'english_name': '', 'description': '', 'category_id': 1}
{'id': 3, 'korean_name': '딸기 딜라이트 요거트 블렌디드', 'english_name': '', 'description': '', 'category_id': 2}
{'id': 5, 'korean_name': '쿠키 블루베리 잼 머핀', 'english_name': '', 'description': '', 'category_id': 3}
{'id': 7, 'korean_name': '벨젯 다크 모카 나이트로', 'english_name': '', 'description': '', 'category_id': 1}
{'id': 10, 'korean_name': '돌체 라떼', 'english_name': '', 'description': '', 'category_id': 3}
In [29]: for bs in b:
...: print(bs['korean_name'])
...:
...:
나이트로 바닐라 크림
미드나잇 베르가못 콜드 브루
딸기 딜라이트 요거트 블렌디드
쿠키 블루베리 잼 머핀
벨젯 다크 모카 나이트로
돌체 라떼
all, get, values
valuesはディクソン形式で戻ります.
objectを返してfield値をすぐに読み込む必要があります.
値は1つしかありません。
getはobjectを返すので、すぐに使用できます.(でもstringタイプ…)
複数の値があります。
このとき考慮できるのはall,valuesである.
1)allを使用する場合
の値は、最初にディック年鑑を含むquerysetを返し、for文を使用してディック年鑑に変換できます.だから.(dot)インポートは使用できません.['key name'でのみインポートできます.
値()を使用しなくてもよいし、値(「フィールド値」)を使用してもよい.
は、このようにしてリストをインポートすることもできる
💡 objectの形態の場合のみ.(dot)を使用してフィールド値を直接取得できます!
django公式ドキュメント-Query set API
Reference
この問題について([TIL.34]DjangoモデルAPI(データインポート-正参照、逆参照)), 我々は、より多くの情報をここで見つけました https://velog.io/@jxxwon/TIL.-34-Django-model-APIテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol