django- IntegrityError - 在添加clean()方法

时间:2017-07-03 15:40:35

标签: django django-validation

我有以下型号。

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 提供了理想的结果 - 当我尝试复制时,我收到了消息

  

此产品组,制造商,产品类型和车轮位置的产品已存在。 -----消息(1)

在(ProductGroup,Manufacturer,ProductType)的组合中,如果存在具有product_type NA的产品,则系统不应允许添加具有TL或TT的另一产品(ProductGroup,Manufacturer)。同样,如果存在TL / TT类型的产品,则应防止添加NA(其他值相同)。

在(ProductGroup,Manufacturer,ProductType,WheelPosition)的组合中,如果存在具有wheel_position C的产品,则系统不应允许添加具有F或B的另一产品(ProductGroup,Manufacturer,ProductType)。同样,如果存在F / B类型的产品,则应防止添加C(其他值相同)。

为了确保这一点,我在表单中添加了一个clean()方法(如下所示)。我认为这个添加完成了所需的工作,当发生unique_key错误时,而不是通过表单显示错误消息,我得到一个未被捕获的完整性错误。

  

/ product / create / 1 /

中的IntegrityError      

重复键值违反了唯一约束   “product_product_product_group_id_manufac_485329c6_uniq”详情:关键字   (product_group_id,manufacturer_id,product_type,wheel_position)=(1,   1,NA,F)已经存在。

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)。

我不知道我错过了什么。

请帮忙。

感谢。

1 个答案:

答案 0 :(得分:0)

您必须调用super()以便父类的clean方法运行并检查检查唯一约束。

def clean(self):
    cleaned_data = super(MyForm, self).clean()
    ...

这应该可以防止完整性错误。