基于外键的下拉列表在Django

时间:2017-01-25 06:30:12

标签: python django django-models django-forms

背景

我正在构建一个基于Django表单的应用程序。表单具有下拉列表,其值来自另一个表(模型)。我在某处读到了使用外键你可以制作动态下拉列表,其值来自源表。

问题:

所有下拉列表都显示相同的值。例如:如果我将值放在国家,aetna,kaiser,bcbs,簇中作为A,B,C,D,E然后在网页上呈现的所有下拉列表中,有B作为选项,而它应该是A的第一个下拉列表,B表示秒,等等。 This is the screenshot of the webpage

为什么会这样?

代码:

models.py

将显示数据的模型1:

class RiskBand(models.Model):
    """Model to store Risk band data"""
    national = models.CharField(
            'National Risk Band',
            max_length=50,
            null=True,
            unique=True  # Required attribute for it to be used as FK
            )
    aetna = models.CharField(
            'Aetna Risk Band',
            max_length=50,
            null=True,
            unique=True
            )
    kaiser = models.CharField(
            'Kaiser Risk Band',
            max_length=50,
            unique=True
            )
    bcbs = models.CharField(
            'BCBS Risk Band',
            max_length=50,
            unique=True
            )
    tufts = models.CharField(
            'TUFTS Risk Band',
            max_length=50,
            unique=True
            )

    def __str__(self):
        return self.aetna

模型2,其中将显示数据:

class ClientRiskBand(TimeStampedModel):
    """Model to store Risk bands for a client set by an underwriter"""
    YEAR_CHOICES = [(r, r) for r in range(1984, datetime.date.today().year+10)]
    year = models.IntegerField(
            'Year',
            choices=YEAR_CHOICES,
            default=datetime.datetime.now().year
            )
    client_name = models.CharField(
            'Client Name',
            max_length=100,
            )
    # Todo : Add sales person field with foreign key from users table
    aetna1 = models.ForeignKey(
            'RiskBand',
            on_delete=models.CASCADE,
            to_field='aetna',
            related_name='aetna1',
            verbose_name='Select Aetna Risk Band 1'
            )
    aetna2 = models.ForeignKey(
            'RiskBand',
            on_delete=models.CASCADE,
            to_field='aetna',
            # https://docs.djangoproject.com/en/1.10/topics/db/queries/#backwards-related-objects
            related_name='aetna_reverse',
            verbose_name='Select Aetna Risk Band 2'
            )
    kaiser = models.ForeignKey(
            'RiskBand',
            on_delete=models.CASCADE,
            to_field='kaiser',
            related_name='kaiser_reverse',
            verbose_name='Select Kaiser Risk Band'
            )
    bcbs = models.ForeignKey(
            'RiskBand',
            on_delete=models.CASCADE,
            to_field='bcbs',
            related_name='bcbs_reverse',
            verbose_name='Select BCBS Risk Band'
            )
    tufts = models.ForeignKey(
            'RiskBand',
            on_delete=models.CASCADE,
            to_field='tufts',
            related_name='tufts_reverse',
            verbose_name='Select TUFTS Risk Band'
            )
    national1 = models.ForeignKey(
            'RiskBand',
            on_delete=models.CASCADE,
            to_field='national',
            related_name='national1_reverse',
            verbose_name='Select National Risk Band 1'
            )
    national2 = models.ForeignKey(
            'RiskBand',
            on_delete=models.CASCADE,
            to_field='national',
            related_name='national2_reverse',
            verbose_name='Select National Risk Band 2'
            )

    class META:
        verbose_name = 'Risk Bands for Client'
        verbose_name_plural = 'Risk Bands for Clients'

    def __str__(self):
        return self.client_name

Forms.py

class ClientRiskBandForm(ModelForm):
    helper = FormHelper()
    helper.form_class = 'form-horizontal'
    helper.label_class = 'col-lg-2'
    helper.field_class = 'col-lg-10'
    helper.layout = Layout(
            'year',
            'client_name',
            'aetna1',
            'aetna2',
            'kaiser',
            'bcbs',
            'tufts',
            'national1',
            'national2',
            FormActions(
                Submit(
                    'save_changes', 'Save Changes', css_class='btn-success'
                    ),
                Submit(
                    'cancel', 'Cancel', css_class='btn-default'),
                    ),
            )

    class Meta:
        model = ClientRiskBand
        fields = {
                'year', 'client_name', 'aetna1', 'aetna2',
                'kaiser', 'bcbs', 'tufts', 'national1', 'national2'
                }

1 个答案:

答案 0 :(得分:0)

您的显示正确。只有一个RiskBand实例,这是由下拉列表提供的(所有字段都是同一模型的外键,其目的对我来说非常模糊)。

下拉列表不会显示指定to_field的值,而是str(instance)(或unicode(instance))。您实施RiskBand.__str__的方式,因此下拉列表将始终显示可用aetna个实例的RiskBand值,无论to_field如何。