django - 在保存表单之前验证DB值

时间:2017-06-16 12:11:39

标签: django django-validation

(首先抱歉模糊标题 - 我不知道如何描述这个标题中的问题)

我有两个模型,如下所示。

PRODUCT_TYPE=(('TL','Tubeless Tyre'), ('TT','Tubed Tyre'), ('NA','Not applicable'))
FRONT_BACK=(('F','Front'), ('B','Back'), ('C','Common'))

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

    opening_stock=models.PositiveIntegerField(default=0)

    def __str__(self):
        return '%s (%s, %s, %s) balance = %d ' % (self.product_group, self.manufacturer, self.product_type ,self.get_balance_stock())

    class Meta:
        unique_together = ('product_group', 'manufacturer','product_type')
    def get_total_stock_in(self):
        return Stock.objects.filter(product=self.id,ttype='I').aggregate(Sum('quantity'))
    def get_total_stock_out(self):
        return Stock.objects.filter(product=self.id,ttype='O').aggregate(Sum('quantity'))
    def get_balance_stock(self):
        return (self.opening_stock+self.get_total_stock_in()['quantity__sum']
                - self.get_total_stock_out()['quantity__sum'])

TRANSACTION_TYPE=(('I','Stock In'),('O','Stock Out'))
class Stock(models.Model):
    product=models.ForeignKey('product.Product', blank=False,null=False)
    date=models.DateField(blank=False, null=False,)
    quantity=models.PositiveIntegerField(blank=False, null=False)
    ttype=models.CharField(max_length=1,verbose_name="Ttransaction type",choices=TRANSACTION_TYPE, blank=False)
    added_date=models.DateTimeField(blank=False, auto_now=True)

我已经制作了一个模型表格和两个单独的视图来记录下面的库存和缺货。

class StockInOutForm(forms.ModelForm):
    class Meta:
        model = Stock
        fields=['product','quantity','date'] #'ttype',
        widgets = {
            'date': forms.DateInput(attrs={'class': 'datepicker'}),
        } 

class StockIn(CreateView):
    model=Stock
    form_class=StockInOutForm
    def get_context_data(self, **kwargs):
        context = super(StockIn, self).get_context_data(**kwargs)
        context['ttype']="Stock In"
        return context
    def form_valid(self, form):
        stockin = form.save(commit=False)
        stockin.ttype = 'I'
        stockin.save()
        return http.HttpResponseRedirect(reverse('stock_list'))

class StockOut(CreateView):
    model=Stock
    form_class=StockInOutForm   
    def get_context_data(self, **kwargs):
        context = super(StockOut, self).get_context_data(**kwargs)
        context['ttype']="Stock Out"
        return context
    def form_valid(self, form):
        stockout = form.save(commit=False)
        stockout.ttype = 'O'
        stockout.save()
        return http.HttpResponseRedirect(reverse('stock_list'))

现在如何防止数量大于可用库存的缺货操作?

我相信我可以从相应的product-object调用方法get_balance_stock(),并将该值与表单中给出的当前quantity进行比较。

请说明如何实施它。

感谢。

1 个答案:

答案 0 :(得分:1)

您应该在表单类上定义clean方法。您可能希望使用单独的子类进行缺货操作,因为此验证仅适用于那些。

class StockOutForm(StockInOutForm):
    def clean(self):
        product = self.cleaned_data['product']
        available = product.get_balance_stock()
        if self.cleaned_data['quantity'] > available:
            raise forms.ValidationError("You can't take out more stock of {} than is available ({})".format(product, available)