Django模型关系

时间:2013-07-20 22:42:07

标签: django django-models django-admin

我有模特

class Event(models.Model):
    name = models.CharField(max_length = 50)

class DriverClass(models.Model):
    name = models.CharField(max_length = 20)
    event = models.ForeignKey(Event)

class Driver(models.Model):
    name = models.CharField(max_length = 50)
    event = models.ForeignKey(Event)
    driverclass = models.ForeignKey(DriverClass)

事件应该有DriverClassDriverDriver可供选择。现在的问题是,DriverClass仅与EventDriverClass相关联,因此当我在django admin为驾驶员选择DriverClass时,我可以从所有Driver es中进行选择。我不确定我的模型中是否可以更改某些内容以完成我想要的内容,或者我是否只需要更改ModelAdmin s {{1}}类以便仅显示正确的事件。什么是正确的程序?

2 个答案:

答案 0 :(得分:4)

您应指定一个自定义ModelForm,用于更改driverclass字段的查询集并将其添加到ModelAdmin

class DriverForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(DriverForm, self).__init__(*args, **kwargs)
        if self.instance.event: 
            # this form has an event specified in either instance, initial or data
            self.fields['driverclass'].queryset = DriverClass.objects.filter(event=self.instance.event)

class DriverAdmin(admin.ModelAdmin):
    form = DriverForm

有一点需要注意的是,当您更改Event时,在您提交表单之前,DriverClass的选项不会更新。表单将抛出ValidationError,并且返回的表单将具有正确的选择。更改此行为需要通过Javascript进行Ajax请求和动态更新。

答案 1 :(得分:0)

Games Brainiac是对的。如果你坚持在驱动程序上有一个事件属性,那就是你可以建模的东西:

class Event(models.Model):
    name = models.CharField(max_length = 50)

class DriverClass(models.Model):
    name = models.CharField(max_length = 20)
    event = models.ForeignKey(Event)

class Driver(models.Model):
    name = models.CharField(max_length = 50)
    driverclass = models.ForeignKey(DriverClass)

    @property
    def event(self):
        return self.driverclass.event

请阅读Django: ForeignKey limit_choices_to to equal current object's client,看看您想要它的方式实际上是一种奇怪的方式'。以您希望的方式保证参照完整性。