我对使用表单处理每个用户的对象有疑问。我想只与与登录用户相关的对象进行交互。
如果我提交表单,它会检查数据库中的每个对象并返回2!当有2个具有相同product_id
的对象时出错。
我使用product_id
字段作为条形码,每个产品都是唯一的,有些用户使用相同的产品。
我尝试先找到一种方法来隔离用户对象,然后再使用数据库。或者还有另一种方法来处理这个问题吗?
据我所知,objects.filter(user=request.user)
无效,因为我需要objects.get
将表单字段的barcode_input
与某个数据库字段相匹配,以减少量。
我在问这个问题之前经常搜索,但我没有搜索技术关键字。
models.py
class ProductModel(models.Model):
user = models.ForeignKey(User)
sku = models.CharField(max_length=100)
product_id = models.CharField(max_length=30, unique=False)
category = models.ForeignKey(ProductCategories, on_delete=models.CASCADE)
quantity = models.IntegerField(default=0)
amount_sold = models.IntegerField(default=0)
def __str__(self):
return self.product_line
forms.py
class ScanProductForm(forms.Form):
barcode_input = forms.CharField(widget=forms.TextInput(attrs={'autofocus': 'autofocus'}))
amount_input = forms.IntegerField(initial=1)
def clean_barcode_input(self):
barcode_input = self.cleaned_data['barcode_input']
qs = ProductModel.objects.filter(product_id=barcode_input)
if qs.exists():
return barcode_input
raise forms.ValidationError("Barcode does not exist")
views.py
def barscan_view(request):
if request.method == 'POST':
form = forms.ScanProductForm(request.POST or None)
if form.is_valid():
barcode_input = form.cleaned_data.get("barcode_input")
amount_input = form.cleaned_data.get("amount_input")
p = ProductModel.objects.get(product_id=barcode_input)
if p.user.username == request.user.username:
if p.quantity >= 0 and amount_input <= p.quantity:
p.amount_sold = F("amount_sold") + amount_input
p.quantity = F("quantity") - amount_input
p.save()
messages.success(request, '%s - %s was successfully scanned' % (p.product_line, p.sku))
return HttpResponseRedirect('overview/scan/')
else:
if p.quantity > 0:
messages.error(request, 'Only %s in stock' %p.quantity)
elif p.quantity is 0:
messages.error(request, 'This product is out of stock')
else:
messages.error(request, 'ID does not match any of your stock')
else:
form = forms.ScanProductForm()
return render(request, 'maninv/scan_product.html', {'form': form})
谢谢,桑德
答案 0 :(得分:0)
也许稍微重新设计一下您的视图逻辑将帮助您实现所需的结果。您可以将ScanProductForm
表单更改为ModelForm
ProductModel
。然后,您可以先使用ProductModel
+ barcode_input
检索request.user
个实例。
<强> forms.py 强>
class ScanProductForm(forms.ModelForm):
barcode_input = forms.CharField(widget=forms.TextInput(attrs={'autofocus': 'autofocus'}))
amount_input = forms.IntegerField(initial=1)
class Meta:
model = ProductModel
fields = ('barcode_input', 'amount_input')
def clean(self):
cleaned_data = super().clean()
amount_input = cleaned_data.get('amount_input')
if self.instance.quantity == 0:
self.add_error(None, 'This product is out of stock')
elif amount_input > self.instance.quantity:
self.add_error(None, 'Only %s in stock' % self.instance.quantity)
return cleaned_data
def save(self, commit=True):
product = super().save(commit=False)
amount_input = cleaned_data.get('amount_input')
product.amount_sold = F('amount_sold') + amount_input
product.quantity = F('quantity') - amount_input
if commit:
product.save()
return product
<强> views.py 强>
def barscan_view(request):
if request.method == 'POST':
product = None
barcode = request.POST.get('barcode_input')
queryset = ProductModel.objects.filter(product_id=barcode)
if queryset.exists():
try:
# the queryset is already filtered by the barcode
# now we apply an extra filter to check if this user has the product
product = queryset.get(user=request.user)
except ProductModel.DoesNotExist:
# here we are sure this product exists, but this user doesnt have it in the stock.
messages.error(request, 'ID does not match any of your stock.')
else:
# here we know this product doesnt exist
messages.error(request, 'Barcode does not exist.')
if product is not None:
form = forms.ScanProductForm(request.POST, instance=product)
if form.is_valid():
form.save()
messages.success(request, '%s - %s was successfully scanned' % (product.product_line, product.sku))
return HttpResponseRedirect('overview/scan/')
else:
form = forms.ScanProductForm()
return render(request, 'maninv/scan_product.html', {'form': form})
但是在一些错误处理方面有一点变化。通过messages.error
传达给用户的一些内容现在是非字段错误。