4

我有三个模型:LineType、Service、DomainName、Record,它们之间有 m2m 或外键关系。这是代码:

class LineType(models.Model):
    linename = models.CharField(max_length=30,primary_key=True)

    def __unicode__(self):
        return self.linename

class Service(models.Model):
    servicename = models.CharField(max_length=30,primary_key=True)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    line = models.ManyToManyField(LineType)

    def __unicode__(self):
        return self.servicename

class DomainName(models.Model):
    domainname = models.CharField(max_length=30,primary_key=True)
    user = models.ForeignKey(SiteProfile)
    service = models.ForeignKey(Service)

    def __str__(self):
        return self.domainname

class Record(models.Model):
    TYPE_CHOICES = (
                ('A','A'),
                ('CNAME','CNAME'),
                ('MX','MX'),
               )
    domainname = models.ForeignKey(DomainName)   

    def get_line(self):
        domain = DomainName.objects.get(pk=self.domainname_id)
        service = Service.objects.get(pk=domain.service_id)
        lines = service.line.all()
        choices = []
        for x in lines:
           choices.append((x.linename,x.linename))
        return choices

    host = models.CharField(max_length=30)
    type = models.CharField(max_length=5,choices=TYPE_CHOICES,default='A')
    line = models.ForeignKey(LineType)
    destaddress = models.CharField(max_length=30)

让我介绍一下模型。每个域名只能有一个其他域名可以拥有的服务。每个域名都有多条记录。服务定义可以应用于记录的 LineTypes。

我使用Django admin来管理这些模型,但是Record中“line”的选择都是LineType对象。所以问题是如何根据它的父(DomainName)的“服务”来过滤Record的LineType。

4

1 回答 1

1

取决于您的确切要求和您的 Django 版本,答案可能是设置limit_choices_to外键的属性,或者自定义 ModelAdmin 表单:

使用limit_choices_to

只需将行选择限制为匹配的行linename == 'foo'

class Record(models.Model):
    # ...
    line = models.ForeignKey(LineType, limit_choices_to={'linename': 'foo'}))

使用自定义form

如果实例化表单时存在实例,我们可以选择它的域服务行作为查询集选项

class RecordAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(RecordAdminForm, self).__init__(*args, **kwargs)

        # access object through self.instance...
        if self.instance:
            valid_lines = self.instance.domainname.service.line.objects.all()
            self.fields['line'].queryset = valid_lines

class RecordAdmin(admin.ModelAdmin):
    form = RecordAdminForm
    # ...

参考SO问题:

于 2016-01-12T15:06:40.087 回答