Django 中间模型中的访问字段
Posted
技术标签:
【中文标题】Django 中间模型中的访问字段【英文标题】:Access fields in Django intermediate model 【发布时间】:2011-01-01 15:12:48 【问题描述】:我正在为中间模型创建 Django 文档中所述的人员组和成员资格。
class Person(models.Model):
name = models.CharField(max_length=128)
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __unicode__(self):
return self.name
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
可以通过以下方式从 Group 对象访问 Person:
>>>Group.members.name
Django 是否创建另一个查询来获取 Person?
我可以从 Group 对象访问date_joined
字段吗?
让我感到困惑的是,我希望得到 Person name 字段:
>>>Group.members.person.name
如果 Person 有一个字段“name”并且中间模型也有一个字段“name”会发生什么。
【问题讨论】:
【参考方案1】:您的示例中的 members 字段是 ManyToManyField,因此它是一种访问多人而不是一个人的方式。 members 字段下的对象实际上是一种特殊类型的 Manager,而不是 Person:
>>> print my_group.members
<django.db.models.fields.related.ManyRelatedManager object at 0x181f7d0>
要更好地了解经理是什么,see the documentation。
要访问一个人的名字,你可以这样做:
>>> for person in my_group.members.all():
>>> print person.name
您无法通过成员字段中的经理访问您的会员模型中的字段。要访问其中的任何字段,您可以:
>>> for membership in my_group.membership_set.all():
>>> print membership.date_joined
因此,如果您的 Membership 模型中有一个名为 name 的字段,您可以像这样访问它:
>>> for membership in my_group.membership_set.all():
>>> print membership.name
访问人名的第二种方法是:
>>> for membership in my_group.membership_set.all():
>>> print membership.person.name
请注意,membership_set
是指向成员的经理的默认名称,但可以通过在相应的外键中指定 related_name
来更改它。例如,如果从 Membership
到 Group
的外键定义如下:
group = models.ForeignKey(Group, related_name="group_members")
然后您将使用group_members
访问管理器:
>>> for membership in my_group.group_members.all():
>>> print membership.name
希望能有所帮助:)
【讨论】:
您所说的非常有道理,并且符合我对 django 模型的理解。让我感到困惑的是在docs.djangoproject.com/en/1.0/topics/db/models/… 上关于 intemedaite 模型的 django 文档,他们用上面相同的模型展示了这个例子: # 查找名称以 'Paul' 开头的成员的所有组 >>> Group.objects.filter(members__name__startswith=' Paul') [使用会员等级的经理:
MyGroup.membership_set.all()
代替:
MyGroup.members.all()
【讨论】:
以上是关于Django 中间模型中的访问字段的主要内容,如果未能解决你的问题,请参考以下文章
在我更改了一些模型字段(Django)之后,尝试访问 django admin 时出现 /admin/myapp/mymodel 的 TypeError