2009-10-07 128 views
3

我有一個模型,其中任務是一些工作,每個工作都可能依賴於其他任務要在完成之前完成的一些任務。任務被分組到作業中,並且我想禁止作業之間的依賴關係。這是我的模型的相關子集:Django:對ManyToManyField映射到自我應用「相同父級」約束

class Job(models.Model): 
    name = models.CharField(max_length=60, unique=True) 

class Task(models.Model): 
    job = models.ForeignKey(Job) 
    prerequisites = models.ManyToManyField(
     'self', 
     symmetrical=False, 
     related_name="dependents", 
     blank=True) 

有什麼辦法,我可以表達所有的先決任務必須具有相同的工作約束?我可能在視圖級別執行此操作,但我真的很想讓它在模型級別上工作,以便在爲任務選擇先決條件時,管理界面將顯示適當的選項。我想我可以使用「limit_choices_to」,但仔細檢查它似乎需要一個靜態查詢,而不是依賴於此任務對象中的值。

回答

3

這裏有兩個單獨的問題。

如果你想在模型層面強制執行這個約束,你可能必須定義一個顯式的「through」模型並覆蓋它的save()方法(你不能只重寫Task.save()爲了將條目添加到M2M,必須被調用)。 Django 1.2將擁有更完整的模型驗證框架,更像表單驗證。

如果您只想在管理員中出現某些選擇,那是表單級問題。您可以動態地設置ModelMultipleChoiceField的查詢集屬性在窗體的初始化方法:

class TaskForm(forms.ModelForm): 
    class Meta: 
     model = Task 

    def __init__(self, *args, **kwargs): 
     super(TaskForm, self).__init__(*args, **kwargs) 
     self.fields['prerequisites'].queryset = Task.objects.filter(job=self.instance.job) 

您可能需要引入一些額外的檢查這裏來處理這種情況下,「自創建新任務(的情況。 instance.job「可能會是None);由於新任務尚未有任何工作,因此您需要的可用前提條件沒有明確定義。

+0

創建多對多關係時調用任務的保存方法嗎?我認爲,因爲它有自己的幕後表,它不會涉及task.save()。 我認爲表單級解決方案是我現在需要的。我還沒有深入研究表格,但是當我有機會回來並接受這個答案時,我會嘗試一下。 – Weeble 2009-10-07 17:10:22

+0

啊,你說得對,在M2M領域,重寫save()是不夠的。有辦法做到這一點,但它可能需要定義一個明確的「通過」模型並重寫其save()方法。我會編輯我的答案的那一部分。 – 2009-10-07 19:46:57

相關問題