Django 模型避免重复
Posted
技术标签:
【中文标题】Django 模型避免重复【英文标题】:Django models avoid duplicates 【发布时间】:2011-03-04 10:29:40 【问题描述】:在模型中:
class Getdata(models.Model):
title = models.CharField(max_length=255)
state = models.CharField(max_length=2, choices=STATE, default="0")
name = models.ForeignKey(School)
created_by = models.ForeignKey(profile)
def __unicode__(self):
return self.id()
在模板中:
<form>
<input type="submit" value="save the data" />
</form>
如果用户点击保存按钮,上面的数据保存在表格中,如何避免重复,即如果用户再次点击同一个提交按钮,不应该有相同值的另一个条目。还是必须在视图中处理?
【问题讨论】:
【参考方案1】:我认为注入 Jquery/JS 代码来隐藏保存按钮是个好主意。
创建一个如下所示的 custom_validate.js 文件并将其放在目录 static(静态文件目录)中
if (!$)
$ = django.jQuery;
$( document ).ready(function()
$("[name=_save]").click(function()
$("[name=_save]").css("visibility", "hidden");
);
);
在 admin.py 中,添加以下代码。
class CustomDataForm(forms.ModelForm):
class Meta:
model = GetData
class GetDataAdmin(admin.ModelAdmin):
# ....
.....
form = CustomDataForm
class Media:
js = ('/static/custom_validate.js', )
【讨论】:
【参考方案2】:unique_together 也建议是最好的方法,但如果这不适合您的需要,您可以在表单的 clean 方法中处理它。例如
def clean(self):
try:
Getdata.objects.get(title=self.cleaned_data['title'],
state=self.cleaned_data['state'],
name=self.cleaned_data['name'],
created_by=self.cleaned_data['created_by'] )
#if we get this far, we have an exact match for this form's data
raise forms.ValidationError("Exists already!")
except Getdata.DoesNotExist:
#because we didn't get a match
pass
return self.cleaned_data
【讨论】:
我还看到,对于多次提交的情况,人们使用 javascript 在单击提交按钮并提交表单时禁用它。最好的解决方案可能是所有这些的组合。 在我的代码中我暂时做了同样的事情..但这与其他人不一致..所以我必须知道这一点..下次我可以使用正确的代码而不是黑客..【参考方案3】:如果单个字段需要唯一,则只需添加unique=True
:
class Getdata(models.Model):
title = models.CharField(max_length=255, unique=True)
state = models.CharField(max_length=2, choices=STATE, default="0")
name = models.ForeignKey(School)
created_by = models.ForeignKey(profile)
如果希望字段组合唯一,则需要unique_together:
class Getdata(models.Model):
title = models.CharField(max_length=255)
state = models.CharField(max_length=2, choices=STATE, default="0")
name = models.ForeignKey(School)
created_by = models.ForeignKey(profile)
class Meta:
unique_together = ["title", "state", "name"]
【讨论】:
另外,当 getdata 在视图中调用第二个示例时,默认情况下这将返回“title”、“state”和“name”是吗? 当您在视图中引用 Getdata 对象时,您将获得一个 Getdata 对象及其所有字段。以上是关于Django 模型避免重复的主要内容,如果未能解决你的问题,请参考以下文章
Django/Python DRY:使用 Q 对象和模型属性时如何避免重复代码
如何避免 Django Forms 和 Django Rest Framework Serializers 中的代码重复?