如何在Django中用单表单修改多模型字段并实现出库扣减库存
Django 模型操作解决方案
一、创建Issue时自动扣减关联Product的库存
首先修正原模型中Product和Customer类的__str__方法缩进错误(原代码中该方法在类外部,无法生效),然后重写Issue类的save方法,结合事务实现库存原子性扣减:
from django.db import models from django.db import transaction class Product(models.Model): name = models.CharField(max_length=50) quantity = models.FloatField(default=0) def __str__(self): return self.name class Customer(models.Model): name = models.CharField(max_length=100) primary_contact = models.CharField(max_length=10) secondary_contact = models.CharField(max_length=10) address = models.TextField(blank=True) def __str__(self): return self.name class Issue(models.Model): date = models.DateTimeField(auto_now_add=True) customer = models.ForeignKey(Customer, on_delete=models.CASCADE) product = models.ForeignKey(Product, on_delete=models.CASCADE) quantity = models.PositiveIntegerField() kt = models.IntegerField() rate = models.FloatField() vat = models.IntegerField(default=15) @property def kt_21(self): return self.kt / 21 * self.quantity @property def vat_amt(self): return self.quantity * self.rate * self.vat/100 @property def total_amt(self): return self.quantity * self.rate + self.vat_amt def __str__(self): return f"{self.customer} - {self.total_amt} SAR" def save(self, *args, **kwargs): # 事务确保库存扣减与Issue创建原子性执行 with transaction.atomic(): # 校验库存是否充足 if self.product.quantity < self.quantity: raise ValueError(f"产品「{self.product.name}」库存不足,当前库存: {self.product.quantity}") # 扣减产品库存 self.product.quantity -= self.quantity self.product.save() # 保存Issue记录 super().save(*args, **kwargs)
二、通过单个表单完成不同模型字段的修改
可以自定义表单整合多模型字段,在表单的clean方法中做数据校验,save方法中分别处理不同模型的保存逻辑:
1. 自定义表单
from django import forms from .models import Issue, Product, Customer class IssueMultiModelForm(forms.Form): # Issue模型字段 customer = forms.ModelChoiceField(queryset=Customer.objects.all()) product = forms.ModelChoiceField(queryset=Product.objects.all()) quantity = forms.IntegerField(min_value=1) kt = forms.IntegerField() rate = forms.FloatField() vat = forms.IntegerField(initial=15) # Product模型可修改字段(示例:修改产品名称) product_name = forms.CharField(max_length=50, required=False, label="修改产品名称(可选)") def clean(self): cleaned_data = super().clean() product = cleaned_data.get("product") quantity = cleaned_data.get("quantity") # 提前校验库存 if product and quantity and product.quantity < quantity: self.add_error("quantity", f"产品「{product.name}」库存不足") return cleaned_data def save(self): with transaction.atomic(): cleaned_data = self.cleaned_data product = cleaned_data["product"] # 修改Product字段(若用户输入了新名称) if cleaned_data.get("product_name"): product.name = cleaned_data["product_name"] product.save() # 创建Issue并自动扣减库存(依赖Issue重写的save方法) issue = Issue.objects.create( customer=cleaned_data["customer"], product=product, quantity=cleaned_data["quantity"], kt=cleaned_data["kt"], rate=cleaned_data["rate"], vat=cleaned_data["vat"] ) return issue
2. 视图中使用表单
from django.shortcuts import render, redirect from .forms import IssueMultiModelForm def create_issue_with_edit(request): if request.method == "POST": form = IssueMultiModelForm(request.POST) if form.is_valid(): form.save() return redirect("issue_list") # 替换为你的Issue列表页面URL else: form = IssueMultiModelForm() return render(request, "create_issue.html", {"form": form})
内容的提问来源于stack exchange,提问作者pip install logic
相关产品推荐
相关产品推荐

