我有这样一个模型:
class DataMapping(models.Model):
company = models.ForeignKey(Company, on_delete=models.CASCADE)
location = models.ForeignKey(Location, null=True, blank=True, on_delete=models.CASCADE)
department = models.ForeignKey(LocationDepartment, null=True, blank=True, on_delete=models.CASCADE)
catagory = models.ForeignKey(CompanyCategory, on_delete=models.CASCADE)
reason = models.ForeignKey(ReasonForProcessing, on_delete=models.CASCADE)
class Meta:
constraints = [
UniqueConstraint(
name='unique_data_map',
fields=['company', 'location', 'department', 'catagory', 'reason'],
condition=Q(location__isnull=False),
violation_error_message="This data map has already been added.",
),
UniqueConstraint(
name='unique_data_map_both_none_dep_none',
fields=['company', 'location', 'catagory', 'reason'],
condition=Q(department__isnull=True),
violation_error_message="This data map has already been added."
),
UniqueConstraint(
name='unique_data_map_both_none',
fields=['company', 'catagory', 'reason'],
condition=Q(location__isnull=True) & Q(department__isnull=True),
violation_error_message="This data map has already been added."
)
]
基本的模型
class DataMapForm(forms.ModelForm):
class Meta:
model = DataMapping
fields = (
'location',
'department',
'catagory',
'reason',
)
widgets = {
'company': forms.HiddenInput()
}
以及以下视图:
def data_mapping_new(request):
company = get_current_logged_in_company(request)
if request.method == "POST":
form = DataMapForm(request.POST or None)
if form.is_valid():
catagory = form.save(commit=False)
catagory.company = company
if form.is_valid():
form.save()
我在不同的模型上有一个类似的设置,工作正常,但这个只是引发了一个错误django.db.utils.IntegrityError: duplicate key value violates unique constraint "unique_data_map_both_none"
它是否应该在第一个if form.is_valid():
处检查约束
我错过了什么?
1条答案
按热度按时间kmbjn2e31#
问题出在
form.save(commit=False)
行,该行不包括满足模型的Meta
类中指定的唯一约束所需的所有字段。调用form.save(commit=False)
时,您将创建尚未保存到数据库的DataMapping
模型的新示例。然后,您将company字段分配给当前公司。但是您没有将值赋给作为唯一约束一部分的其他字段。尝试在调用
form.save()
之前添加这些字段,如下所示:上面的解决方案应该可以工作,但是另外我建议您查看由Sir Willem Van Onsem制作的
Using request.POST or None
反模式。