当输入与Django中的行匹配时,如何更改现有数据库中的值

时间:2017-07-12 09:33:15

标签: django-models django-forms django-views

我在这个网站上搜索了很多并找到了我的部分问题,但这个我找不到。也许我没有使用正确的关键字,这是一个常见问题吗?如果是这样的道歉。

我正在尝试将名为barcode_input的输入值与名为barcode的模型字段的表单进行匹配。 如果匹配,则打印(“有匹配!”)将显示在终端中。

下一步将是,当匹配时,必须将amount_input值添加到特定模型已售出字段(与之匹配)并从特定模型amount_sold字段中减去(使用该字段时)一场比赛)。

到目前为止,这是我的代码。

models.py

from django.db import models

class AddProduct(models.Model):
    title = models.CharField(max_length=255)
    barcode = models.IntegerField(default=0, primary_key=True)
    stock_amount = models.IntegerField(default=0)
    sold = models.IntegerField(default=0)

    def __str__(self):
        return self.title

    class Meta:
        verbose_name_plural = "Products"

forms.py

from django import forms
from .models import AddProduct

class ScanProductForm(forms.Form):
    barcode_input = forms.IntegerField(label='scan barcode')
    amount_input = forms.IntegerField(label='amount')
    def clean(self):
        cleaned_data = super(ScanProductForm, self).clean()
        barcode_input = cleaned_data.get("barcode_input")
        amount_input = cleaned_data.get("amount_input")

        try:
            p = AddProduct.objects.get(pk=barcode_input)
            p.sold += amount_input
        except AddProduct.DoesNotExist:
            raise forms.ValidationError("Does not exist")

views.py

from django.shortcuts import render
from .forms import ScanProductForm

from .models import AddProduct

def scan_product_view(request):
    if request.method == 'POST':

        form = ScanProductForm(request.POST or None)

        if form.is_valid():
                print("There is a match!")
        else:
            form = ScanProductForm()

        return render(request, 'scanapp/barscan.html', {'form': form})

1 个答案:

答案 0 :(得分:0)

你应该使用Django的F表达式进行这类工作 的 forms.py

from django.db.models import F
from django import forms
from .models import AddProduct

class ScanProductForm(forms.Form):
    barcode_input = forms.IntegerField(label='scan barcode')
    amount_input = forms.IntegerField(label='amount')
    def clean(self):
        cleaned_data = super(ScanProductForm, self).clean()
        barcode_input = cleaned_data.get("barcode_input")
        amount_input = cleaned_data.get("amount_input")

        try:
            p = AddProduct.objects.get(pk=barcode_input)

            p.sold = F('sold') +  amount_input
            p.save()
        except AddProduct.DoesNotExist:
            raise forms.ValidationError("Does not exist")
  

更好的方法是仅验证forms.py中的条形码输入字段   并将更新对象的逻辑移到views.py。


forms.py

class ScanProductForm(forms.Form):
    barcode_input = forms.IntegerField(label='scan barcode')
    amount_input = forms.IntegerField(label='amount')
    def clean_barcode_input(self):
        barcode_input = self.cleaned_data['barcode_input']
        qs = AddProduct.objects.filter(pk=barcode_input)
        if qs.exists():
            return barcode_input
        raise forms.ValidationError("Barcode does not exist")

<强> views.py

from django.shortcuts import render
from django.db.models import F
from .forms import ScanProductForm
from .models import AddProduct

def scan_product_view(request):
    if request.method == 'POST':
        form = ScanProductForm(request.POST or None)
        if form.is_valid():
            print("There is a match!")
            barcode_input = form.cleaned_data.get("barcode_input")
            amount_input = form.cleaned_data.get("amount_input")
            p = AddProduct.objects.get(pk=barcode_input)
            p.sold = F("sold") + amount_input
            p.save()
        else:
            form = ScanProductForm()
        return render(request, 'scanapp/barscan.html', {'form': form})