2014-10-28 33 views
1

我正在通過Membership模型與PersonProject模型編寫一個簡單的應用程序,它們具有多對多的關係。只有一個Membership可以存在於任何兩個給定的PersonProject對象之間。目前,可以通過PersonProject更改表單內嵌添加新的Membership對象。Django - 避免在許多到中間模型中重複

這工作正常,但有一個用戶意外創建冗餘Membership的問題。我給自己定一個unique_together約束在Membership模型中的兩個外鍵,但是這有兩個問題:

  1. 當保存新的父對象中,Membership模型的任何冗餘的情況下被保存而不引起任何形式的錯誤。
  2. 修改現有對象時,添加冗餘Membership會觸發預期的錯誤消息,但不會顯示相應內聯的刪除圖標,並且無法刪除已保留的對象之一,因爲該錯誤會阻止任何對象數據庫操作不再發生。

我想知道在保存父對象並刪除任何冗餘對象之前迭代通過membership_set集合的正確方法是什麼。

+0

還有其他一些問題。 'unique_together'是一個數據庫級的約束,在Django中沒有什麼可以做的,這會導致創建冗餘行。所以如果你看到多餘的行,問題是你的'unique_together'工作不正常。你確定你已經遷移了這個變化,並且它已經被應用到數據庫了嗎?你能看看你的數據庫並確認約束存在嗎?你真的能看到你認爲已經創建的重複行嗎? – 2014-10-28 21:41:35

+0

感謝您的建議,事實證明我沒有運行相應的遷移。但是,現在當我保存一個新的父對象時,我得到一個服務器異常而不是驗證錯誤,所以我仍然有問題。 – jflorezf 2014-10-29 17:13:06

回答

1

這是我在我的項目是如何做:

#Models.py 
class Person(models.Model): 
    user = models.OneToOneField(User, primary_key=True) 
    field = models.CharField(max_length=128) 

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    members = models.ManyToManyField(Person, through='Membership') 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    date_joined = models.DateField() 
    invite_reason = models.CharField(max_length=64) 

視圖

#views.py 
class GroupDetails(generic.DetailView): 

model = Group 
template_name = 'app/template.html' 
form_class = SomeForm 

    def post(self, request, *args, **kwargs): 
     form = self.form_class(request.POST) 

     #get group 
     group = self.get_object(queryset=Group.objects.all()) 

     #get person 
     person = Person.objects.get(pk=request.user) 

     #check if objects exists before save 
     if Membership.objects.filter(person = person, group = group).exists(): 
      messages.error(request, 'Oh this is duplicated') 
      return HttpResponseRedirect(reverse('view-name', kwargs={'pk': group.pk})) 

     else: 

      if form.is_valid(): 
       form.save(commit=False) 

       #assign to the through table 
       persontogroup = Membership.objects.create(person = person, group = group) 

       persontogroup.save() 

       messages.success(request, 'Success!') 

     return HttpResponseRedirect('/something/') 

希望這有助於。您也可以檢查:Avoid Django def post duplicating on save

+0

感謝您的回答。問題是我正在使用默認的管理界面。我認爲您提供的鏈接可以提供幫助,因此我會檢查並告訴您。 – jflorezf 2014-10-29 17:14:38