Django外键后向关系不起作用

时间:2017-09-27 21:25:44

标签: django django-models

我有一个B类,它包含与A类的ForeignKey关系。当我实例化B时,我可以访问字段' a'但是反向关系(应该自动创建)会引发错误。具体来说,我有以下类定义:

from django.db.models import Model, CharField, DateField, ForeignKey
from django.urls import reverse

class Patient(Model):

    GENDER = (
        ('M', 'Male'),
        ('F', 'Female'),
        ('U', 'Unknown'),
    )

    last_name = CharField(max_length=128, null=False)
    first_name = CharField(max_length=128, null=False, default='')
    gender = CharField(max_length=1, choices=GENDER, null=False)
    dob = DateField(null=False)

    def get_absolute_url(self):
        return reverse('patient_detail', args=[str(self.id)])

    def __str__(self):
        return '{}, {} ({}, {})'.format(self.last_name, self.first_name, self.gender, self.dob)


class AttributeSet(Model):

    name = CharField(max_length=128, null=False)
    description = CharField(max_length=256, blank=True, default='')

    def get_absolute_url(self):
        return reverse('attribute_set_detail', args=[str(self.id)])

    def __str__(self):
        return self.name


class AttributeSetInstance(Model):

    patient = ForeignKey('Patient', null=False) # Automatic 'attribute_set_instance_set' backward relation?
    attribute_set = ForeignKey('AttributeSet', null=False)

    def get_absolute_url(self):
        return reverse('attribute_set_instance_detail', args=[str(self.id)])

    def __str__(self):
        return self.attribute_set.name

当我尝试使用Patient和AttributeSet参数创建新的AttributeSetInstance时,我可以访问patient和attribute_set字段,但反之亦然。像这样:

Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 12:39:47) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from app.models import Patient, AttributeSet, AttributeSetInstance
>>> p = Patient(last_name='Doe', first_name='John', gender='M', dob='1973-07-16')
>>> p
<Patient: Doe, John (M, 1973-07-16)>
>>> a = AttributeSet(name='Set1')
>>> a
<AttributeSet: Set1>
>>> i = AttributeSetInstance(patient=p, attribute_set=a)
>>> i
<AttributeSetInstance: Set1>
>>> i.patient
<Patient: Doe, John (M, 1973-07-16)>
>>> i.attribute_set
<AttributeSet: Set1>
>>> p.attribute_set_instance_set
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Patient' object has no attribute 'attribute_set_instance_set'
>>>

所以,i.patient工作,但是p.attribute_set_instance_set没有。据我所知,分配给ForeignKey关系的默认管理器附加了一个&#39; _set&#39;后缀为后向关系。

知道我做错了什么吗?这将是非常有帮助的。 这可能是愚蠢的......

拉​​尔夫

1 个答案:

答案 0 :(得分:1)

您添加了下划线,不应该有任何下划线。默认相关名称是模型的小写名称加上_set,因此对于AttributeSetInstance,它是attributesetinstance_set

如果要使用下划线版本,可以将其设置为ForeignKey字段的显式related_name参数。