15. models.py
class SushiTopping(models.Model):
"""タコ、サワラ、シメサバなどの具材"""
name = models.CharField(max_length=255)
class Menu(models.Model):
"""お品書き"""
name = models.CharField(max_length=255, unique=True)
price = models.IntegerField(default=0)
sushi_toppings = models.ManyToManyField(SushiTopping)
class Sale(models.Model):
sales_date = models.DateTimeField()
menu = models.ForeignKey(Menu, on_delete=models.PROTECT)
26. Field lookups
Field lookups are how you specify the meat of an SQL WHERE
clause.
https://docs.djangoproject.com/ja/2.2/ref/models/querysets/#field-lookups
フィールドルックアップは、SQLのWHERE句の中身を指定
する方法です。
39. models.py
class SushiTopping(models.Model):
"""タコ、サワラ、シメサバなどのトッピング"""
name = models.CharField(max_length=255)
class Menu(models.Model):
"""お品書き"""
name = models.CharField(max_length=255, unique=True)
price = models.IntegerField(default=0)
sushi_toppings = models.ManyToManyField(SushiTopping)
class Sale(models.Model):
sales_date = models.DateTimeField()
menu = models.ForeignKey(Menu, on_delete=models.PROTECT)
40. models.py
class SushiTopping(models.Model):
"""タコ、サワラ、シメサバなどのトッピング"""
name = models.CharField(max_length=255)
class Menu(models.Model):
"""お品書き"""
name = models.CharField(max_length=255, unique=True)
price = models.IntegerField(default=0)
sushi_toppings = models.ManyToManyField(SushiTopping)
class Sale(models.Model):
sales_date = models.DateTimeField()
menu = models.ForeignKey(Menu, on_delete=models.PROTECT)
75. for s in Sale.objects.select_related("menu").all():
s.menu.name
select_related:
SELECT
…(略) …
FROM
sales_sale
INNER JOIN
sales_menu
ON (sales_sale.menu_id = sales_menu.id);
77. for m in Menu.objects.all():
for st in m.sushi_toppings.all():
st.name
(0.003) SELECT "sales_menu"."id", "sales_menu"."name", "sales_menu"."price", "sales_menu"."features" FROM "sales_menu";
(0.003) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 1;
(0.004) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 2;
(0.003) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 3;
(0.002) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 4;
(0.002) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 5;
(0.002) SELECT "sales_sushitopping"."id", "sales_sushitopping"."name" FROM "sales_sushitopping" INNER JOIN
"sales_menu_sushi_toppings" ON ("sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id") WHERE
"sales_menu_sushi_toppings"."menu_id" = 6;
やっぱり!
78. 浅はかな僕は何も考えず同じ事をする
for m in Menu.objects.select_related(‘sushi_toppings’).all():
for st in m.sushi_toppings.all():
st.name
django.core.exceptions.FieldError: Invalid field
name(s) given in select_related: 'sushi_toppings'.
Choices are: (none)
80. for m in Menu.objects.prefetch_related('sushi_toppings').all():
for st in m.sushi_toppings.all():
st.name
SQLは2本になった!
SELECT ...(略)... FROM "sales_menu";
SELECT
...(略)...(sales_menu_sushi_toppings.menu_id) AS _prefetch_related_val_menu_id,
ON (
"sales_sushitopping"."id" = "sales_menu_sushi_toppings"."sushitopping_id"
)
WHERE
sales_menu_sushi_toppings.menu_id IN(1, ...(略)... 15);
101. よく分からないので公式を見ます
Per-object summaries can be generated using the annotate() clause. When an annotate()
clause is specified, each object in the QuerySet will be annotated with the specified values.
The syntax for these annotations is identical to that used for the aggregate() clause. Each
argument to annotate() describes an aggregate that is to be calculated.
https://docs.djangoproject.com/ja/2.2/topics/db/aggregation/#generating-aggregat
es-for-each-item-in-a-queryset