django- IntegrityError - 添加 clean() 方法后重复键值违反唯一约束
django- IntegrityError - duplicate key value violates unique constraint after adding clean() method
我有以下型号。
FRONT_BACK=(('F','Front'), ('B','Back'), ('C','Common'))
PRODUCT_TYPE=(('TL','Tubeless Tyre'), ('TT','Tubed Tyre'), ('NA','Not applicable'))
class Product(models.Model):
product_group=models.ForeignKey('productgroup.ProductGroup', null=False,blank=False)
manufacturer=models.ForeignKey(Manufacturer, null=False,blank=False)
product_type=models.CharField(max_length=2, choices=PRODUCT_TYPE, null=False,blank=False)
wheel_position=models.CharField(max_length=1, choices=FRONT_BACK, null=False,blank=False)
opening_stock=models.PositiveIntegerField(default=0)
stock_in=models.PositiveIntegerField(verbose_name="Stock in so far", default=0)
stock_out=models.PositiveIntegerField(verbose_name="Stock out so far", default=0)
created_by=models.ForeignKey(auth.models.User, default=1)
class Meta:
ordering=['product_group','manufacturer']
unique_together = ('product_group', 'manufacturer','product_type','wheel_position')
unique_together
给出了想要的结果 - 当我尝试复制时,我收到消息
Product with this Product group, Manufacturer, Product type and Wheel position already exists. -----message(1)
在 (ProductGroup,Manufacturer,ProductType) 的组合中,如果存在具有 product_type NA 的产品,系统不应允许为相同的 (ProductGroup,Manufacturer) 添加另一个具有 TL 或 TT 的产品).同样,如果存在 TL/TT 类型的产品,则应避免添加 NA(其他值相同)。
在 (ProductGroup,Manufacturer,ProductType,WheelPosition) 的组合中,如果存在具有 wheel_position C 的产品,系统不应允许为相同的产品添加具有 F 或 B 的其他产品(ProductGroup ,制造商,产品类型)。同样,如果存在 F/B 类型的产品,则应避免添加 C(其他值相同)。
为了确保这一点,我在我的表单中添加了一个 clean() 方法(如下所附)。我认为这个添加完成了预期的工作 但是 ,当 unique_key 错误发生时,我没有通过表单显示错误消息,而是收到未捕获的完整性错误。
IntegrityError at /product/create/1/
duplicate key value violates unique constraint
"product_product_product_group_id_manufac_485329c6_uniq" DETAIL: Key
(product_group_id, manufacturer_id, product_type, wheel_position)=(1,
1, NA, F) already exists.
def clean(self):
print(self.cleaned_data)
if self.cleaned_data['product_type'] == 'NA':
tl=f=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= 'TL')
tt=f=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= 'TT')
if tl.exists() :
url = reverse('product_detail', kwargs={'pk': tl[0].id})
raise forms.ValidationError({'product_type':
[mark_safe("<a href=\"%s\">Product Type: TL </a> exists for this combination. N/A is not allowed" % url)]})
elif tt.exists():
url = reverse('product_detail', kwargs={'pk': tt[0].id})
raise forms.ValidationError({'product_type':
[mark_safe("<a href=\"%s\">Product Type: TT </a> exists for this combination. N/A is not allowed" % url)]})
else:
na=f=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= 'NA')
if na.exists():
url = reverse('product_detail', kwargs={'pk': na[0].id})
raise forms.ValidationError({'product_type':
[mark_safe('<a href="%s"> Product type N/A </a> already exists for this combination.' % url) ]})
if self.cleaned_data['wheel_position'] == 'C':
f=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= self.cleaned_data['product_type'],
wheel_position='F')
b=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= self.cleaned_data['product_type'],
wheel_position='B')
if f.exists() :
url = reverse('product_detail', kwargs={'pk': f[0].id})
raise forms.ValidationError({'wheel_position':
[mark_safe("<a href=\"%s\">Wheel position: Front</a> exists for this combination. Common is not allowed" % url ) ]})
elif b.exists():
url = reverse('product_detail', kwargs={'pk': b[0].id})
raise forms.ValidationError({'wheel_position':
[mark_safe("<a href=\"%s\">Wheel position: Back</a> exists for this combination. Common is not allowed" % url )]})
else:
c=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= self.cleaned_data['product_type'],
wheel_position='C')
if c.exists():
url = reverse('product_detail', kwargs={'pk': c[0].id})
raise forms.ValidationError({'wheel_position':
[mark_safe("<a href=\"%s\"> Wheel position: Common </a> exists for this combination." % url)]})
这是查询结果。
Product.objects.filter(product_group=1, manufacturer=1,product_type='NA')
<QuerySet [<Product: 1000.20.16 (CEAT, NA, F)>,
<Product: 1000.20.16 (CEAT, NA, B)>]>
当我评论 clean() 方法时,系统会显示有关 unique_key 重复的正确消息,如上所示(---- 消息 1)。
我不知道我错过了什么。
请帮忙。
谢谢。
您必须调用 super()
以便父 class' clean 方法运行并检查唯一约束。
def clean(self):
cleaned_data = super(MyForm, self).clean()
...
这应该可以防止完整性错误。
我有以下型号。
FRONT_BACK=(('F','Front'), ('B','Back'), ('C','Common'))
PRODUCT_TYPE=(('TL','Tubeless Tyre'), ('TT','Tubed Tyre'), ('NA','Not applicable'))
class Product(models.Model):
product_group=models.ForeignKey('productgroup.ProductGroup', null=False,blank=False)
manufacturer=models.ForeignKey(Manufacturer, null=False,blank=False)
product_type=models.CharField(max_length=2, choices=PRODUCT_TYPE, null=False,blank=False)
wheel_position=models.CharField(max_length=1, choices=FRONT_BACK, null=False,blank=False)
opening_stock=models.PositiveIntegerField(default=0)
stock_in=models.PositiveIntegerField(verbose_name="Stock in so far", default=0)
stock_out=models.PositiveIntegerField(verbose_name="Stock out so far", default=0)
created_by=models.ForeignKey(auth.models.User, default=1)
class Meta:
ordering=['product_group','manufacturer']
unique_together = ('product_group', 'manufacturer','product_type','wheel_position')
unique_together
给出了想要的结果 - 当我尝试复制时,我收到消息
Product with this Product group, Manufacturer, Product type and Wheel position already exists. -----message(1)
在 (ProductGroup,Manufacturer,ProductType) 的组合中,如果存在具有 product_type NA 的产品,系统不应允许为相同的 (ProductGroup,Manufacturer) 添加另一个具有 TL 或 TT 的产品).同样,如果存在 TL/TT 类型的产品,则应避免添加 NA(其他值相同)。
在 (ProductGroup,Manufacturer,ProductType,WheelPosition) 的组合中,如果存在具有 wheel_position C 的产品,系统不应允许为相同的产品添加具有 F 或 B 的其他产品(ProductGroup ,制造商,产品类型)。同样,如果存在 F/B 类型的产品,则应避免添加 C(其他值相同)。
为了确保这一点,我在我的表单中添加了一个 clean() 方法(如下所附)。我认为这个添加完成了预期的工作 但是 ,当 unique_key 错误发生时,我没有通过表单显示错误消息,而是收到未捕获的完整性错误。
IntegrityError at /product/create/1/
duplicate key value violates unique constraint "product_product_product_group_id_manufac_485329c6_uniq" DETAIL: Key (product_group_id, manufacturer_id, product_type, wheel_position)=(1, 1, NA, F) already exists.
def clean(self):
print(self.cleaned_data)
if self.cleaned_data['product_type'] == 'NA':
tl=f=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= 'TL')
tt=f=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= 'TT')
if tl.exists() :
url = reverse('product_detail', kwargs={'pk': tl[0].id})
raise forms.ValidationError({'product_type':
[mark_safe("<a href=\"%s\">Product Type: TL </a> exists for this combination. N/A is not allowed" % url)]})
elif tt.exists():
url = reverse('product_detail', kwargs={'pk': tt[0].id})
raise forms.ValidationError({'product_type':
[mark_safe("<a href=\"%s\">Product Type: TT </a> exists for this combination. N/A is not allowed" % url)]})
else:
na=f=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= 'NA')
if na.exists():
url = reverse('product_detail', kwargs={'pk': na[0].id})
raise forms.ValidationError({'product_type':
[mark_safe('<a href="%s"> Product type N/A </a> already exists for this combination.' % url) ]})
if self.cleaned_data['wheel_position'] == 'C':
f=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= self.cleaned_data['product_type'],
wheel_position='F')
b=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= self.cleaned_data['product_type'],
wheel_position='B')
if f.exists() :
url = reverse('product_detail', kwargs={'pk': f[0].id})
raise forms.ValidationError({'wheel_position':
[mark_safe("<a href=\"%s\">Wheel position: Front</a> exists for this combination. Common is not allowed" % url ) ]})
elif b.exists():
url = reverse('product_detail', kwargs={'pk': b[0].id})
raise forms.ValidationError({'wheel_position':
[mark_safe("<a href=\"%s\">Wheel position: Back</a> exists for this combination. Common is not allowed" % url )]})
else:
c=Product.objects.filter(product_group=self.cleaned_data['product_group'],
manufacturer=self.cleaned_data['manufacturer'],
product_type= self.cleaned_data['product_type'],
wheel_position='C')
if c.exists():
url = reverse('product_detail', kwargs={'pk': c[0].id})
raise forms.ValidationError({'wheel_position':
[mark_safe("<a href=\"%s\"> Wheel position: Common </a> exists for this combination." % url)]})
这是查询结果。
Product.objects.filter(product_group=1, manufacturer=1,product_type='NA')
<QuerySet [<Product: 1000.20.16 (CEAT, NA, F)>,
<Product: 1000.20.16 (CEAT, NA, B)>]>
当我评论 clean() 方法时,系统会显示有关 unique_key 重复的正确消息,如上所示(---- 消息 1)。
我不知道我错过了什么。
请帮忙。
谢谢。
您必须调用 super()
以便父 class' clean 方法运行并检查唯一约束。
def clean(self):
cleaned_data = super(MyForm, self).clean()
...
这应该可以防止完整性错误。