2013-07-20 98 views
4

我有機型Django的模型關係

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) 

事件應該有DriverClass ES爲Driver一套量可供選擇。現在的問題是Driver只連接到DriverClassEvent,所以當我在django admin中爲驅動程序選擇DriverClass時,我可以從所有的DriverClass es中選擇。我不確定在我的模型中是否有某些東西可以改變,以便完成我想要的功能,或者我只需要更改類別以便僅顯示正確的事件。什麼是正確的程序?

+0

什麼是'Driver'選擇'DriverClass'的過濾條件? – karthikr

+0

驅動程序與一個事件相關聯,然後與事件的驅動程序類相關聯。 – Martol1ni

+1

我相信你的模型是不健全的。像這樣看,你有一個'Event',一個事件可以有很多'DriverClass'。精細。因此,一個'DriverClass'已經與一個事件相關聯,因此與某個'DriverClass'關聯的'Driver'已經連接到一個事件,他們不是?我仍然沒有得到你想要的。 –

回答

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,並且返回的表單將有正確的選擇。改變這種行爲將需要Ajax請求和通過Javascript進行動態更新。

+0

我能做到這一點,這是常規的做法嗎? – Martol1ni

+0

@ Martol1ni我想是的,通常的做法是覆蓋表單的'__init__'方法來處理這種動態的,每個實例的變化,我認爲這正是字段的'queryset'屬性的作用。 – knbk

+0

@ Martol1ni如果您對此答案感到滿意,您能否接受並解決此問題? – knbk

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,看到你想要的方式實際上是「不可思議的方式」。您希望的方式不保證參考完整性。