【发布时间】:2010-11-03 15:29:15
【问题描述】:
2 个问题:
- 当 parent=None 且名称相同时,如何阻止创建重复项?
- 我可以从表单中调用模型方法吗?
请参阅下面的完整详细信息:
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。帮忙!
另外,(有点完全不同的问题)我可以从表单访问 make_slug() 模型方法吗?我相信目前我的exclude = ('slug',) 行也忽略了 slug 字段上的“唯一”约束,而在模型保存字段中,我正在生成 slug。我想知道是否可以改为在 forms.py 中执行此操作?
【问题讨论】:
-
请参阅stackoverflow.com/questions/3488264/… 了解处理此问题的最新方法。需要 Django 1.2。
-
使用 Django2.2,您可以使用带有条件参数的 UniqueConstraints 来创建部分索引:docs.djangoproject.com/en/2.2/ref/models/constraints/#condition
标签: django django-models django-forms