奇怪:为什么 Django 相关的多对多查找以这种方式工作(但不像在文档中那样)?
Strange: why Django related many-to-many lookup works this way (but not like in docs)?
Django 文档描述了如何查询反向 m2m 字段:
https://docs.djangoproject.com/en/1.8/topics/db/queries/#many-to-many-relationships
根据 this answer 我们应该使用 related_name
作为查询中的第一个参数。
但我无法完成这项工作。 (我正在使用 Django 1.8.5)。这是我的示例模型:
class Nlpneutralfeature(models.Model):
neutral_feature = models.CharField(u'found word', max_length=255, default='')
class Userproject(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="project", verbose_name=("owner"))
monitoring_words = models.ManyToManyField(Nlpneutralfeature, null=True, blank=True, related_name="monitoringwords")
name = models.CharField(u'Название проекта', unique=True, max_length=255)
因此,要获取属于 Userproject
的所有 Nlpneutralfeature
行,其中 Userproject.name == '48'
,我需要执行以下操作:
Nlpneutralfeature.objects.filter(userproject__monitoringwords__name='48')
但这不起作用。我得到的错误是:Cannot resolve keyword *'userproject'* into field
.
因此,Django 无法理解 'userproject' 是小写的模型名称 Userproject.
现在,这是有效的:
Nlpneutralfeature.objects.filter(monitoringwords__name='48')
Django 怎么知道 monitoringwords
是 related_name
?没有错误对我来说很奇怪,因为 Nlpneutralfeature
模型中没有 monitoringwords
字段!
注意 Django docs 中的措辞:
The name to user for the relation from the related object back to this one. It's also the default value for related_query_name (the name to use for the reverse filter name from the target model).
在您的示例中,"target model" 是 Nlpneutralfeature
。当您在 ManyToManyField Userproject.monitoringwords
上设置 related_name = 'monitoringwords'
时,它告诉 Django 使用 related_name
从 Nlpneutralfeature
模型对象 back 引用到相应的 Userproject
模型对象。
相应地,如果你用related_name = 'foo'
声明了Userproject.monitoringwords
,那么查询属于项目48的所有Nlpneautralfeatures
的方式是:Nlpneautralfeature.objects.filter(foo__name='48')
.
此处的 related_name
使您可以获得与 Nlpneutralfeature
模型相关的 Userproject 模型。
例如:
nf = Nlpneutralfeature.objects.get(neutral_feature="XXX")
# From here you can get all Userprojects related to this nf like this:
userProjects = nf.monitoringwords.all()
如果你没有声明 related_name 那么你必须这样做:
nf = Nlpneutralfeature.objects.get(neutral_feature="XXX")
# From here you can get all Userprojects related to this nf like this:
userProjects = nf.Userproject_set.all()
我认为你通过逆向理解了这个属性..在我看来你应该在这里声明它是这样的:related_name="user_projects"
总而言之,related_name 是当您想从相关模型中获取当前模型(您声明 M2M 关系的地方)时使用的。
Django 文档描述了如何查询反向 m2m 字段: https://docs.djangoproject.com/en/1.8/topics/db/queries/#many-to-many-relationships
根据 this answer 我们应该使用 related_name
作为查询中的第一个参数。
但我无法完成这项工作。 (我正在使用 Django 1.8.5)。这是我的示例模型:
class Nlpneutralfeature(models.Model):
neutral_feature = models.CharField(u'found word', max_length=255, default='')
class Userproject(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="project", verbose_name=("owner"))
monitoring_words = models.ManyToManyField(Nlpneutralfeature, null=True, blank=True, related_name="monitoringwords")
name = models.CharField(u'Название проекта', unique=True, max_length=255)
因此,要获取属于 Userproject
的所有 Nlpneutralfeature
行,其中 Userproject.name == '48'
,我需要执行以下操作:
Nlpneutralfeature.objects.filter(userproject__monitoringwords__name='48')
但这不起作用。我得到的错误是:Cannot resolve keyword *'userproject'* into field
.
因此,Django 无法理解 'userproject' 是小写的模型名称 Userproject.
现在,这是有效的:
Nlpneutralfeature.objects.filter(monitoringwords__name='48')
Django 怎么知道 monitoringwords
是 related_name
?没有错误对我来说很奇怪,因为 Nlpneutralfeature
模型中没有 monitoringwords
字段!
注意 Django docs 中的措辞:
The name to user for the relation from the related object back to this one. It's also the default value for related_query_name (the name to use for the reverse filter name from the target model).
在您的示例中,"target model" 是 Nlpneutralfeature
。当您在 ManyToManyField Userproject.monitoringwords
上设置 related_name = 'monitoringwords'
时,它告诉 Django 使用 related_name
从 Nlpneutralfeature
模型对象 back 引用到相应的 Userproject
模型对象。
相应地,如果你用related_name = 'foo'
声明了Userproject.monitoringwords
,那么查询属于项目48的所有Nlpneautralfeatures
的方式是:Nlpneautralfeature.objects.filter(foo__name='48')
.
此处的 related_name
使您可以获得与 Nlpneutralfeature
模型相关的 Userproject 模型。
例如:
nf = Nlpneutralfeature.objects.get(neutral_feature="XXX")
# From here you can get all Userprojects related to this nf like this:
userProjects = nf.monitoringwords.all()
如果你没有声明 related_name 那么你必须这样做:
nf = Nlpneutralfeature.objects.get(neutral_feature="XXX")
# From here you can get all Userprojects related to this nf like this:
userProjects = nf.Userproject_set.all()
我认为你通过逆向理解了这个属性..在我看来你应该在这里声明它是这样的:related_name="user_projects"
总而言之,related_name 是当您想从相关模型中获取当前模型(您声明 M2M 关系的地方)时使用的。