Python 仅从Django ORM获取一个相关对象

Python 仅从Django ORM获取一个相关对象,python,django,django-models,Python,Django,Django Models,以下是我正在处理的模型的精简版本: class Contact(models.Model): contact_no = models.IntegerField(primary_key=True) email_address = models.CharField(max_length=60, null=True) class ContactRole(models.Model): contact_no = models.ForeignKey(Contact, primary

以下是我正在处理的模型的精简版本:

class Contact(models.Model):
    contact_no = models.IntegerField(primary_key=True)
    email_address = models.CharField(max_length=60, null=True)

class ContactRole(models.Model):
    contact_no = models.ForeignKey(Contact, primary_key=True, db_column='contact_no')
    role_code = models.CharField(primary_key=True, max_length=16)
    role_scope_code = models.CharField(primary_key=True, max_length=16)
联系人可以而且几乎总是有许多联系人角色

我想要一个联系人列表,其中相关联系人角色的角色\u范围\u代码为“foo”。我知道我可以通过以下方式获得此信息:

Contact.objects.filter(contactrole__role_scope_code='foo')
我还希望queryset中的每个联系人都有一个.contactrole属性。它将是角色范围代码为“foo”的ContactRole。相反,我将获得一组与contact\u no匹配的所有ContactRole,因此要访问ContactRole的属性,我必须执行以下操作:

contacts = Contact.objects.filter(contactrole__role_scope_code='foo')
for contact in contacts:
    print contact.contactrole_set.filter(role_scope_code='foo')[0].role_code
contacts = Contact.objects.filter(contactrole__role_scope_code='foo')
for contact in contacts:
    print contact.contactrole.role_code
我必须对角色\范围\代码进行两次筛选!看起来一点也不干。我要找的是一个查询,它允许我有一个这样的集合:

contacts = Contact.objects.filter(contactrole__role_scope_code='foo')
for contact in contacts:
    print contact.contactrole_set.filter(role_scope_code='foo')[0].role_code
contacts = Contact.objects.filter(contactrole__role_scope_code='foo')
for contact in contacts:
    print contact.contactrole.role_code

在我的一生中,我不知道如何告诉Django只返回与我应用于父对象的筛选器相匹配的相关对象。A
OneToOneField
将解决此问题,前提是联系人只有一个contactrole。一个
OneToOneField
为您提供了所需的api。因此,不要使用
ForeignKey
而是使用
OneToOneField

虽然我认为这是正确的,但问题是将该关系从ForeignKey更改为OneToOne错误地描述了这两个表之间的关系。在将来的某个时候,可能有人需要查看与联系人关联的所有ContactRole。问题是,对于外键关系,可能有两个ContactRole对象,其角色为\u scope\u code='foo'。因此,按照我的理解,使用
contact.contactrole.role\u code
访问它是不可能的。如果只有一个对象,则可以使用
contact.contactrole.get().role\u code
,但如果存在多个contactrole,则该对象将中断。此外,如果要将
contactrole\u set
的名称更改为
contactroles
请在外键中使用
相关的\u name='contactroles'