2009-06-17 54 views
6

2個問題:模型unique_together約束+無=失敗?

  • 我怎樣才能阻止被創建時父=無和名稱是一樣的重複?
  • 我可以從窗體內調用模型方法嗎?

請參見下面的完整細節:

models.py

class MyTest(models.Model): 
    parent = models.ForeignKey('self', null=True, blank=True, related_name='children') 
    name = models.CharField(max_length=50) 
    slug = models.SlugField(max_length=255, blank=True, unique=True) 
    owner = models.ForeignKey(User, null=True) 

    class Meta: 
     unique_together = ("parent", "name") 

    def save(self, *args, **kwargs): 
     self.slug = self.make_slug() 
     super(MyTest, self).save(*args, **kwargs) 

    def make_slug(self): 
     # some stuff here 
     return generated_slug 

注:蛞蝓=獨一無二的!

forms.py

class MyTestForm(forms.ModelForm): 
    class Meta: 
     model = MyTest 
     exclude = ('slug',) 

    def clean_name(self): 
     name = self.cleaned_data.get("name") 
     parent = self.cleaned_data.get("parent") 

     if parent is None: 
      # this doesn't work when MODIFYING existing elements! 
      if len(MyTest.objects.filter(name = name, parent = None)) > 0: 
       raise forms.ValidationError("name not unique") 
     return name 

詳細

unique_together contraint完美的作品W /表單時parent != None。但是,當parent == None(空)它允許重複創建。

爲了嘗試和避免這種情況,我嘗試使用窗體並定義clean_name來嘗試檢查重複項。這在創建新對象時起作用,但在修改現有對象時不起作用。

有人提到過我應該在ModelForm的.save中使用commit = False,但我無法弄清楚如何去做/實現它。我也考慮過使用ModelForm的has_changed來檢測對模型的更改並允許它們,但has_changed也會使用該窗體在新創建的對象上返回true。幫幫我!另外,(有點完全不同的問題)我可以從Form中訪問make_slug()模型方法嗎?我相信,目前我的exclude = ('slug',)行也忽略了slug字段上的'唯一'約束,並且在模型保存字段中,我改爲生成slug。我想知道我是否可以在forms.py中做到這一點?

+0

見http://stackoverflow.com/questions/3488264/django-unique-一起工作 - 與外部關鍵 - 沒有一個處理這個問題的最新方法。需要Django 1.2。 – 2011-07-23 19:03:52

回答

-1

我不確定這會解決您的問題,但我建議您在最新的Django中繼代碼上測試您的代碼。用得到它:

svn co http://code.djangoproject.com/svn/django/trunk/ 

已經有一些修正,因爲1.02的釋放unique_together,例如見ticket 9493

+0

即時通訊已經在運行中繼線 – lostincode 2009-06-17 21:45:56

-1

獨特在一起應該是元組

unique_together = (("parent", "name"),) 
+0

這已不再需要 – lostincode 2009-06-17 21:46:32

0

的元組你可以有不同的形式,無論您是創建或更新。

實例化表單時使用實例kwarg。

if slug: 
    instance = MyTest.object.get(slug=slug) 
    form = MyUpdateTestForm(instance=instance) 
else: 
    form = MyTestForm() 

對於第二部分,我認爲這就是你可以帶來犯=假像:

if form.is_valid(): 
    inst = form.save(commit=False) 
    inst.slug = inst.make_slug() 
    inst.save()