Django how to build an invoice that gives the user the ability to add multiple items?

时间:2018-01-15 18:21:46

标签: django python-3.x django-models django-views e-commerce

I am trying to build a e-shop using django 2.0, but I have a 'logic' question not a syntax one, how to build an invoice that can accept many Items? In other words I have a model for the invoice item that is connected To a product model but I do not know how to build an invoice view that That gives the user the ability to add multiple items to this invoice How to do so knowing that I use CBV for the views? Thanks in advance

1 个答案:

答案 0 :(得分:1)

您要找的是 formsets 。基本上,您创建一个普通的产品表单,然后将formset_factory应用于它以创建 formset ,这是一个可移动的对象。 https://docs.djangoproject.com/en/2.0/topics/forms/formsets/

还有一些变体,例如模型formset ,它接受填充表单的查询。我不确定你的项目,但值得看看这些不同的版本。

编辑:

我很难准确猜出你需要什么,因为我无法准确地看到应用程序及其视图。下面我创建了一个简单的示例,允许您创建一个附有2个订单行的新发票。如果要编辑现有发票,则必须添加一个实例,用于表单初始化,例如

order_formset = OrderFormSet(request.POST, initial=...)

如果要添加2个以上的订单行,则必须将模板中的表单复制到模板中。这可以通过java / jquery实现,有很多关于如何执行此操作的示例。我建议四处寻找适合您需求的产品。总的来说,jquery代码将复制第一个/最后一个表单并将其粘贴到模板中,清除新副本的所有值,并更新表单中输入的id。参见例如Dynamically adding a form to a Django formset with Ajax

示例:

models.py

class Invoice(models.Model):
    ...

class Order(models.Model):
    ...
    ordered = models.ForeignKey('Invoice', related_name = 'orderline')

forms.py:

class InvoiceForm(ModelForm):
    class Meta:
        model = Invoice
        fields = ['field_names_go_here']

class OrderForm(ModelForm):
    class Meta:
        model = Order
        fields = ['field_names_go_here']

views.py

def create_order(request):

    if request.method == 'POST':

        invoice = InvoiceForm(request.POST)
        if invoice.is_valid():
            invoice.save()

        OrderFormSet = formset_factory(OrderForm)
        order_formset = OrderFormSet(request.POST)

        if order_formset.is_valid():

            new_orders = []
            for order_form in order_formset:
                new order = Order(
                    ...
                    ordered = invoice,
                )
                new_orders.append(order)

            Order.objects.bulk_create(new_orders)

        return ...

    if request.method == 'GET':

       invoice_form = InvoiceForm()

       OrderFormSet = formset_factory(OrderForm, extra=2)
       order_formset = OrderFormSet()

       template_context = {
           'invoice_form': invoice_form,
           'order_formset': order_formset,
           }

       template = 'template_name.html'

       return render(request, template, template_context)

模板

<form enctype="multipart/form-data" action="{% url 'some_url_name' %}" method="post">
    {% csrf_token %}

        {{ order_formset.management_form }}

        {{ invoice_form }}

        {% for order_form in order_formset %}
             {{ order_form }}
        {% endfor %}

        <input type="submit" value="submit" />
</form>

EDIT2: 我发现您可能预订了可以订购的物品。在这种情况下,您需要做的就是设置多对多关系,生成订单对象列表,在模板中显示它们,并为每个订单添加一个表单/按钮,将它们添加到某个发票中。这可以通过添加包含Order对象的pk的隐藏输入来实现。然后你甚至不需要为表格集烦恼。

相关问题