Djangoで使用される `related_name`は何ですか?


391

related_nameon ManyToManyFieldおよびForeignKeyfieldsに役立つ引数は何ですか?たとえば、次のコードの場合、どのような影響がありrelated_name='maps'ますか?

class Map(db.Model):
    members = models.ManyToManyField(User, related_name='maps',
                                     verbose_name=_('members'))

12
@DanielRoseman逆方向の関係が必要ない場合にrelated_name = '+'を使用することは、パフォーマンスまたは優れた慣行にとってなんとなく良いことですか。
lajarre 2012年

10
@lajarreの質問に対する答えを知りたいです。
3cheesewheel 2013

1
@lajarre-パフォーマンスがまったく変化しないと思います。FeinCMSコンテンツタイプで一度使用する必要がありました。私は個人的には常に指定するのが良い習慣だと思うrelated_nameので、それを使用しないことがわかっている場合は、それは良いことだと思います。もちろんそれは個人的な意見です。
フランソワ・コンスタント

@ 3cheesewheelそれは今ドキュメントにあります:docs.djangoproject.com/en/2.0/ref/models/fields/… +は逆の関係を作成しないことを意味します
P. Myer Nore

回答:


531

このrelated_name属性は、Userモデルからモデルに戻る逆関係の名前を指定します。

たとえば、を指定しない場合related_name、Djangoはモデルの名前にサフィックスを付けて自動的に作成_setしますUser.map_set.all()

あなたがいる場合行う、などを指定するrelated_name=mapsにはUserモデル、User.map_setまだ仕事がしますが、User.maps.構文は明らかにビットクリーナーと少ない不格好です。たとえば、ユーザーオブジェクトがあった場合current_user、を使用current_user.maps.all()Mapて、と関係のあるモデルのすべてのインスタンスを取得できますcurrent_user

Djangoのドキュメントには、より多くの詳細を持っています。


1
わかりました、これは古い投稿です。しかし、私はこれを理解しようとしています-関連する名前の最後の+トリックは何ですか?たとえば、related_name='maps+'上の例で行った場合はどうなりますか?
シッド、2014年

10
+を追加すると、djangoはマッピングを無効にします
josephmisiti

5
OneToOneFieldのデフォルトでは、related_nameは小文字のクラス名になります。たとえば、上記の例では、メンバーがOneToOnefieldの場合、「User.map」が機能します。
アンチョ2014年

あなたが指定した場合related_name_setまだ動作しますdjango1.11 >か?
Esir Kings

9
私はDjango 2.1.3を使用していますが、これらは排他的なものです。一度related_name指定すると、_set動作しなくなります。
stockersky 2018

84

既存の回答に追加するには-モデルに同じテーブルを指す2つのFKがある場合、関連する名前は必須です。たとえば、部品表の場合

@with_author 
class BOM(models.Model): 
    name = models.CharField(max_length=200,null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    tomaterial =  models.ForeignKey(Material, related_name = 'tomaterial')
    frommaterial =  models.ForeignKey(Material, related_name = 'frommaterial')
    creation_time = models.DateTimeField(auto_now_add=True, blank=True)
    quantity = models.DecimalField(max_digits=19, decimal_places=10)

したがって、このデータにアクセスする必要がある場合は、関連する名前しか使用できません

 bom = material.tomaterial.all().order_by('-creation_time')

それ以外の場合は機能しません(同じテーブルに2つのFKがある場合、関連する名前の使用をスキップできませんでした)。


2
少なくともそのうちの1つについて、related_nameを選択する必要があります。もう1つは必ずしも必要ではありません。
Csaba Toth

32
related_name複数である必要があります。これは、ForeignKeyリレーションが複数のオブジェクトを返すためです。
Mesut Tasci

11

このrelated_name引数は、関連するクラス名がより複雑な場合にも役立ちます。たとえば、外部キー関係がある場合:

class UserMapDataFrame(models.Model):
    user = models.ForeignKey(User) 

UserMapDataFrame関連するからオブジェクトにアクセスするためUserのデフォルトの呼び出しはでありUser.usermapdataframe_set.all()、これを読むのは非常に困難です。

を使用related_nameすると、より単純で読みやすい名前を指定して、逆の関係を取得できます。この場合、を指定するuser = models.ForeignKey(User, related_name='map_data')と、呼び出しはになりますUser.map_data.all()


3

関連名パラメーターは、実際にはオプションです。設定しない場合、Djangoは自動的に関係の反対側を作成します。Mapモデルの場合、Djangoはmap_set属性を作成m.map_setし、例(mはクラスインスタンス)でのアクセスを許可します。Djangoが使用する式は、モデル名の後に文字列が続きます_set。したがって、関連する名前パラメーターは、新しい動作を提供するのではなく、単にDjangoのデフォルトをオーバーライドします。


0

prefetch_related多対多および多対1の関係データのプリフェッチデータに使用します。 select_related単一の値の関係からデータを選択することです。これらはどちらも、モデルからの関係からデータをフェッチするために使用されます。たとえば、モデルと、他のモデルと関係があるモデルを作成します。リクエストが来ると、リレーションシップデータのクエリも行われます。Djangoには、リレーションシップからデータにアクセスするための非常に優れたメカニズムbook.author.nameがあります。これを克服するには prefetchd_relatedselected_related

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.