2009-06-17 60 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()