模型unique_together约束+无=失败?

los*_*ode 6 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
Run Code Online (Sandbox Code Playgroud)

注意: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
Run Code Online (Sandbox Code Playgroud)

细节

这种情况下,unique_together约束力与形式完美结合parent != None.但是当parent == None(null)时,它允许创建重复项.

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

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

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

Van*_*ale -1

我不确定这是否会解决您的问题,但我建议在最新的 Django 主干代码上测试您的代码。获取它:

svn co http://code.djangoproject.com/svn/django/trunk/
Run Code Online (Sandbox Code Playgroud)

自 1.02 版本发布以来,对 unique_together 进行了多项修复,例如,请参阅票证 9493