模型unique_together约束+无=失败?

时间:2009-06-17 12:11:38

标签: django django-models django-forms

2个问题:

  • 当parent = None且name相同时,如何阻止创建重复项?
  • 我可以从表单中调用模型方法吗?

请参阅以下详细信息:

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

注意: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约束与parent != None时的表单完美匹配。但是,当parent == None(null)时,它允许创建重复项。

为了尝试避免这种情况,我尝试使用表单并定义了clean_name来尝试检查重复项。这在创建新对象时有效,但在修改现有对象时不起作用。

有人曾提到我应该在ModelForm的.save上使用commit = False,但我无法弄清楚如何执行/实现它。我还考虑过使用ModelForm的has_changed来检测模型的变化并允许它们,但是has_changed在新创建的对象上也返回true。帮助!

另外,(有点完全不同的问题)我可以从Form访问make_slug()模型方法吗?我相信目前我的exclude = ('slug',)行也忽略了slug字段上的'unique'约束,而在模型save字段中,我正在生成slug。我想知道我是否可以在forms.py中执行此操作?

3 个答案:

答案 0 :(得分:0)

无论您是创建还是更新,都可以使用不同的格式。

在实例化表单时使用实例kwarg。

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

对于第二部分,我认为这是你可以引入commit = False的地方,如:

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

答案 1 :(得分:-1)

我不确定这会解决您的问题,但我建议您在最新的Django中继代码上测试您的代码。得到它:

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

自1.02发布以来,对unique_together进行了多次修复,例如,请参阅ticket 9493

答案 2 :(得分:-1)

独特在一起应该是一个元组元组

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