select-related, prefetch-related


QuerySet API reference | Django documentation | Django

これは何ですか。


The only reason to use either of these methods is when a single large query is preferable to many small queries. Django uses the large query to create models in memory preemptively rather than performing on demand queries against the database.
関連関数を使用するのは、大きなクエリが小さなクエリよりもパフォーマンスが優れているためです.
Djangoは、クエリーをDBに送信するときに、オンデマンドクエリーではなく大きなクエリーを使用して、メモリにモデルを事前に作成します.

select-related


選択するオブジェクトが逆参照の単一オブジェクト(1対1または複数対1)または外部キーを参照している場合に使用します.
各検索はSQLのJOINを実行してテーブルの一部を取得します.select...から関連フィールドを取得します.
from drink.models import *

drink = Drink.objects.get(id=1) 🎯
Category.objects.filter(id = drink.category.category_id) 🎯

drink_sr = Drink.objects.select_related('category').get(id=1) 🎯
drink_sr.category.name

prefetch-related


Returns a  QuerySet  that will automatically retrieve, in a single batch, related objects for each of the specified lookups.
複数のオブジェクト(複数対複数または1対複数)を正または逆参照するForeign Keyに使用します.prefetch_related , on the other hand, does a separate lookup for each relationship, and does the ‘joining’ in Python.
prefetch-relatedはそれぞれqueryを発行し、pythonでマージします.
from drink.models import *

drink_pr = Category.objects.filter(id=1).prefetch_related("drink_set") 🎯
Category.objects.filter(id = drink.category.category_id) 🎯

drink_sr = Drink.objects.select_related('category').get(id=1) 🎯
drink_sr.category.name

Understanding ForeignKey


parent&childの関係を考えると、理解しやすくなります.
  • ForeignKeyはchildに指定することが望ましい.
  • 多対多関係では、ForeignKeyはより低いレベルに指定することが望ましい.
  • ForeignKeyを持つChild  lookup(__)を使用して、親フィールドを参照できます.
  • >>> Drink.objects.filter(sub_category__name='cold brew')
    <QuerySet [<Drink: dolce cold brew>, <Drink: cold brew>]>
  • parentは、そのサブフィールドを同様の方法で参照することもできる.
  • このときchild classの名前は小文字で記入します.
  • >>> SubCategory.objects.filter(drink__calories__gt=300)
    <QuerySet [<SubCategory: cold brew>, <SubCategory: cold brew>]>

    ForeignKeyと正参照と逆参照

  • FKを持つクラスが持たないクラスを参照する場合は、正参照
  • を参照してください.
  • FKクラスのクラスを参照する場合は、逆参照
  • を使用します.
    class ModelA(models.Model):
        pass
    
    class ModelB(models.Model):
        a = ForeignKey(ModelA)
    
    ModelB.objects.select_related('a').all() # Forward ForeignKey relationship
    ModelA.objects.prefetch_related('modelb_set').all() # Reverse ForeignKey relationship