首页 > 解决方案 > Django 模型没有更新

问题描述

我创建了一个优惠券系统,其中每个用户最初在员工表中都有 500 作为余额。我想通过用户通过 html 表单提供的金额来减少此余额。以下是我的文件:

模型.py

from django.db import models
from django.contrib.auth.models import User
import django
import datetime
# Create your models here.



class vendor(models.Model):
    id = models.CharField(max_length=20, primary_key=True)
    name = models.CharField(max_length=30)

class employee(models.Model):
    name = models.OneToOneField(User, on_delete=models.CASCADE)
    id = models.CharField(max_length=20, primary_key=True)
    balance = models.IntegerField(default=0)

class transaction(models.Model):
    vendor_id = models.ForeignKey(vendor, on_delete=models.CASCADE)
    emp_id = models.ForeignKey(employee, on_delete=models.CASCADE)
    debit = models.IntegerField()
    credit = models.IntegerField()
    timestamp = models.DateField(("Date"), default=datetime.date.today)

视图.py

def updatingBalance(request):
    if request.method=="POST":
        ven_id = request.POST["groupOfDefaultRadios"]
        amount = request.POST["amt"]
        x = employee.objects.get(name = request.user)
        x.balance = x.balance - int(amount)
        v = vendor.objects.get(id=ven_id)
        w = employee.objects.get(id=x.id)
        transaction.objects.create(vendor_id = v, emp_id=w,debit=amount,credit=0)
        y = employee.objects.get(name = request.user)
        #print(y.balance)
        return render(request, 'profiles/userLogin.html', {'model':employee})
    return render(request, 'profiles/userLogin.html')

html表单:

{% if model %}
    <h3>Balance amount is {{ model.balance }}</h3>
{% endif %}
    <h3>Select vendor to pay!</h3>
    <br>
<form method="POST" action="/profiles/userLogin/">
        <div class="custom-control custom-radio">
              <input type="radio" class="custom-control-input" id="defaultGroupExample1" name="groupOfDefaultRadios" value="1">
              <label class="custom-control-label" for="defaultGroupExample1">Vendor 1</label>
            </div>

            <div class="custom-control custom-radio">
              <input type="radio" class="custom-control-input" id="defaultGroupExample2" name="groupOfDefaultRadios" value="2">
              <label class="custom-control-label" for="defaultGroupExample2">Vendor 2</label>
            </div> 
        <input type="" class="form-control" id="amount1" name="amt" aria-describedby="emailHelp" placeholder="Enter amount">
        <br>
        <button type="submit" class="btn btn-primary">Submit</button>

    </form> 

我哪里错了?如何直接引用员工模型?我知道 x 可能没有正确引用模型。另外,我需要在 html 上显示余额。怎样才能做到这一点?

标签: htmldjangodjango-modelsdjango-views

解决方案


这不起作用的原因是因为你从来没有.save()你的Employee对象。此外,如果 POST 请求成功,您应该重定向以实现Post/Redirect/Get模式 [wiki]

from django.shortcuts import redirect

def updatingBalance(request):
    if request.method=="POST":
        ven_id = request.POST["groupOfDefaultRadios"]
        amount = request.POST["amt"]
        x = employee.objects.get(name=request.user)
        x.balance = x.balance - int(amount)
        x.save()
        v = vendor.objects.get(id=ven_id)
        w = employee.objects.get(id=x.id)
        transaction.objects.create(vendor_id=v, emp_id=w, debit=amount, credit=0)
        return redirect(updatingBalance)
    y = employee.objects.get(name = request.user)
    return render(request, 'profiles/userLogin.html', {'model': y})

话虽如此,我强烈建议不要将余额存储在Employee模型中。保持平衡正确更新会产生很多麻烦,例如竞争条件。

相反,您可以创建一个注释,为员工计算余额:

class EmployeeManager(models.Manager):

    def get_queryset(self):
        return super().get_queryset().annotate(
            balance=Sum(F('transaction__credit')-F('transaction__debit'))
        )

class Employee(models.Model):
    name = models.OneToOneField(User, on_delete=models.CASCADE)
    id = models.CharField(max_length=20, primary_key=True)
    # no balance
    objects = EmployeeManager()

因此,在这里我们将计算相关Transaction对象的聚合。

在这种情况下,视图是:

from django.shortcuts import redirect

def updatingBalance(request):
    if request.method=="POST":
        ven_id = request.POST["groupOfDefaultRadios"]
        amount = request.POST["amt"]
        x = employee.objects.get(name=request.user)
        v = vendor.objects.get(id=ven_id)
        transaction.objects.create(vendor_id=v, emp_id=x, debit=amount, credit=0)
        return redirect(updatingBalance)

    y = employee.objects.get(name=request.user)
    return render(request, 'profiles/userLogin.html', {'model': y})

所以我们不需要更新余额字段,它只是通过添加交易来更新。

注意:通常是 Django 模型,就像 Python 中的所有类都在PerlCase中命名,而不是snake_case,所以它应该是:Employee而不是employee.

 

注意:当您将对象传递给模板时,它不是模型,而是模型对象。因此,您可能希望将变量的名称从 更改'model''employee'


推荐阅读