您能解释一下 Django 中 Field 对象的
related_name
和 related_query_name
属性之间的区别吗?当我使用它们时,如何使用它们?谢谢!
related_name
将是相关对象的属性,它允许您“向后”到带有外键的模型。例如,如果 ModelA
具有如下字段:model_b = ForeignKeyField(ModelB, related_name='model_as')
,则您可以通过转至 ModelA
来访问与您的 ModelB
实例相关的 model_b_instance.model_as.all()
实例。请注意,外键通常用复数形式编写,因为外键是一对多关系,而该等式的多方是在其上声明了外键字段的模型。
文档中链接的进一步解释很有帮助。 https://docs.djangoproject.com/en/dev/topics/db/queries/#backwards-lated-objects
related_query_name
用于 Django 查询集。它允许您过滤外键相关字段的反向关系。继续我们的示例 - 在 Model A
上有一个字段,如下所示:
model_b = ForeignKeyField(ModelB, related_query_name='model_a')
将使您能够使用 model_a
作为查询集中的查找参数,例如:ModelB.objects.filter(model_a=whatever)
。更常见的是使用单数形式来表示 related_query_name
。正如文档所说,没有必要指定两个(或其中一个)related_name
和related_query_name
。 Django 有合理的默认值。
class Musician(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
class Album(models.Model):
artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
这里外键前向关系是专辑到音乐家,后向关系是音乐家到专辑。这意味着一个专辑实例只能与一个音乐家实例相关(前向关系),而一个音乐家实例可以与多个专辑实例相关(后向关系)。
正向查询会是这样的
Album_instance.artist
注意这里的前向查询由Album_instance 和艺术家(字段名称)完成。向后将是
Musician_instance.album_set.all()
这里使用 modelname_set 进行反向查询。
现在,如果您指定 related_name,如
artist = models.ForeignKey(Musician, on_delete=models.CASCADE, related_name='back')
然后向后查询语法将更改 modelname_set(artist.set) 将被 back 替换。 现在向后查询
Musician_instance.back.all()
如果您不希望 Django 创建向后关系,请将 related_name 设置为“+”或以“+”结尾。
和 related_query_name 用于目标模型中的反向过滤器名称
我用实际例子来解释一下Django模型中
related_name
和related_query_name
的区别。
class Post(models.Model):
title = models.CharField(max_length=100)
class Comment(models.Model):
sentence = models.CharField(max_length=255)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
默认情况下,Django 设置:
related_name = 'comment_set'
(用于反向关系访问)related_query_name = 'comment'
(用于过滤)这会导致以下行为:
# Using related_query_name (for filtering)
Post.objects.filter(comment__title="XYZ") # ✅ Valid
Post.objects.filter(comment_set__title="XYZ") # ❌ Error
# Using related_name (for accessing related objects)
post_obj.comment_set.all() # ✅ Valid
post_obj.comment.all() # ❌ Error
class Post(models.Model):
title = models.CharField(max_length=100)
class Comment(models.Model):
sentence = models.CharField(max_length=255)
post = models.ForeignKey(
Post,
on_delete=models.CASCADE,
related_name="mycomments" # Custom related_name
)
当您指定自定义
related_name
时,Django会自动使用:
related_name = 'mycomments'
related_query_name = 'mycomments'
(匹配 related_name,除非明确覆盖)这会导致:
# Using related_query_name (for filtering)
Post.objects.filter(mycomments__sentence="XYZ") # ✅ Valid
Post.objects.filter(comment_set__sentence="XYZ") # ❌ Error
# Using related_name (for accessing related objects)
post_obj.mycomments.all() # ✅ Valid
post_obj.comment_set.all() # ❌ Error
related_name
用于访问反向关系(例如,获取帖子的所有评论)related_query_name
用于查询集中进行过滤related_name
,Django 对 related_query_name
related_query_name
:post = models.ForeignKey(
Post,
related_name='mycomments',
related_query_name='post_comment',
on_delete=models.CASCADE
)
这将允许:
Post.objects.filter(post_comment__sentence="XYZ") # Uses related_query_name
post_obj.mycomments.all() # Uses related_name