为什么Django无法正确更新ModelForm?

时间:2020-05-22 22:08:04

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

我正在为有特定需求的客户在项目管理网站上工作。 将项目添加到DB可以很好地工作。当我更新项目时,这些字段会随我输入的内容进行更新。但是它没有像addProject()那样执行必要的计算。我可以单击“提交”,并且在调用updateProject()时请求将通过,但是它不会计算任何内容。

views.py:

def calculate(subtotal, no_of_signs, sign_permit, engineering, other_fees, discount, cash_discount, tax):
    total = subtotal + (sign_permit * no_of_signs) + engineering + other_fees
    tax_amount = float(tax) * total
    total += tax_amount

    if discount > 0:
        total -= total * discount
    elif cash_discount > 0:
        total -= cash_discount
    else:
        return total
    return total


def addProject(request):
    form = ProjectForm()
    if request.method == 'POST':
        # form_copy = request.POST.copy()
        form_copy = request.POST
        # get data used to calculate total
        #  .....
        mutable = request.POST._mutable
        request.POST._mutable = True

        # ......
        number_of_signs = int(form_copy['number_of_signs'])
        sign_permit = float(form_copy['sign_permit'])
        engineering = float(form_copy['engineering'])
        other_fees = float(form_copy['other_fees'])
        # project can have discount OR cash discount
        discount = (float(form_copy['discount']) * .01)
        cash_discount = float(form_copy['cash_discount'])
        # total after discount applied
        discount_total = float(form_copy['discount_total'])
        deposit_amount = float(form_copy['deposit_amount'])
        completion_amount = float(form_copy['completion_amount'])
        # calculate percentage
        deposit_percentage = float(form_copy['deposit_percentage'])
        # form_copy['completion_percentage'] = 100 - deposit_percentage
        request.POST['completion_percentage'] = 100 - deposit_percentage

        # calculate total sign price as subtotal
        # calculate subtotal given sign price
        sum = 0
        for i in range(number_of_signs):
            i += 1
            sign_order = 'mysign-' + str(i)
            sum += int(form_copy[sign_order])
            print(sum)
        form_copy['subtotal'] = sum
        subtotal = float(form_copy['subtotal'])

        # if discount %, discount total = disocunt * subtotal
        # if cash discount, discount total = subtotal - cash discount
        if discount:
            form_copy['discount_total'] = discount * subtotal
        elif cash_discount:
            form_copy['discount_total'] = cash_discount

        # calculate total price
        # form_copy['final_total'] = subtotal
        form_copy['final_total'] = calculate(
            subtotal, number_of_signs, sign_permit, engineering, other_fees, discount, cash_discount, form_copy['tax'])

        form_copy['deposit_amount'] = (form_copy['final_total'] - (form_copy['final_total'] *
                                                                form_copy['completion_percentage'] * .01))

        form_copy['completion_amount'] = (form_copy['final_total'] -
                                        form_copy['deposit_amount'])

        form = ProjectForm(form_copy)
        if form.is_valid():
            request.POST._mutable = mutable
            form.save()
            return redirect('/')
    context = {
        'form': form,
    }
    return render(request, 'pages/add_project_form.html', context)

def updateProject(request, pk):
    project = Project.objects.get(id=pk)
    form = ProjectForm(instance=project)

    if request.method == 'POST':
        form = ProjectForm(request.POST, instance=project)
        # sum = 0

        # for i in range(int(request.POST['number_of_signs'])):
        #     i += 1
        #     sign_order = 'mysign-' + str(i)
        #     sum += int(form[sign_order])
        #     print(sum)
        # form['subtotal'] = sum
        # subtotal = float(form['subtotal'])

        if form.is_valid():
            form.save()
            return redirect('/')

    context = {
        'form': form,
    }
    return render(request, 'pages/add_project_form.html', context)

模板:add_project_form.html

    {% extends 'base.html' %}

    {% block content %}
            <div class="container">
                        <form action="" method="POST" style="">
                            <div class="row">
                                {% csrf_token %}
                                <div class="col-sm">
                                    <table>
                                    {{form.as_table}}
                                    </table>
                                </div>
                                <div class="col-sm">
                                    <div class="container1">
                                        <button class="add_form_field">Add New Sign &nbsp; 
                                            <span style="font-size:16px; font-weight:bold;">+ </span>
                                        </button>
                                        <div>
                                                <input id="sign-1" type="text" name="mytext-1" placeholder="Sign Name">
                                                <input id="price-1" type="number" name="mysign-1" placeholder="Sign Price">
                                        </div>
                                    </div>
                                    <input class='btn btn-primary' type="submit" name="submit" style="margin: 25px; min-width: 100%">
                                </div>
                            </div>

                        </form>

            </div>
    {% endblock content %}

base.html中的脚本,用于根据符号计算小计。

        <script type='text/javascript'>
            $(document).ready(function() {
                let max_fields = 10;
                let wrapper = $(".container1");
                let add_button = $(".add_form_field");

                let x = 1;
                $(add_button).click(function(e) {
                    e.preventDefault();
                    if (x < max_fields) {
                        x++;
                        $(wrapper).append(`<div><input id="sign-${x} "type="text" name="mytext-${x}" placeholder="Sign Name"/><input id="price-${x} "type="number" name="mysign-${x}" placeholder="Sign Price"/><a href="#" class="delete">Delete</a></div>`); //add input box
                    } else {
                        alert('You Reached the limits')
                    }
                });

                $(wrapper).on("click", ".delete", function(e) {
                    e.preventDefault();
                    $(this).parent('div').remove();
                    x--;
                })
            });
    </script>

1 个答案:

答案 0 :(得分:0)

将尝试回答并为您提供一些改进建议

  1. 您的代码有很多可能的改进(例如,将计算移至模型中(如果您遵循“使模型保持胖并且控制器变薄”))
  2. 读取PEP8,最好将addProject重命名为add_project,将updateProject重命名为update_project,但更好的选择是制作一个基于类的视图处理POST以创建并打补丁以更新表单。这样,您可以使用1个视图来创建和更新
  3. 税金计算是一种使用我猜测的货币的操作,在这种情况下,十进制是首选类型
  4. 您可以使用Django的redirect('/')代替直接使用reverse
  5. 您应该使用Django forms,以避免用strfloat等包装值的麻烦,因为Django表单会将提交的数据验证并序列化为Python类型。

现在,关于您的直接问题,似乎在调用updateProject时您没有进行任何修改。

您应以正确的方式使用forms.ModelForm来获取数据并修改模型中的值。即在save()或属性中。