【问题标题】:Django how to build an invoice that gives the user the ability to add multiple items?Django如何建立一个发票,让用户能够添加多个项目?
【发布时间】:2018-01-15 18:21:46
【问题描述】:

我正在尝试使用 django 2.0 建立一个电子商店,但我有一个“逻辑”问题而不是语法问题,如何建立一个可以接受很多的发票 项目?换句话说,我有一个已连接发票项目的模型 到产品模型,但我不知道如何构建发票视图 这使用户能够向此发票添加多个项目 知道我使用 CBV 作为视图怎么办? 提前致谢

【问题讨论】:

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


    【解决方案1】:

    您正在寻找的是表单集。基本上你创建一个普通的产品form,然后将formset_factory应用到它以创建一个formset,它是一个可迭代的对象。 https://docs.djangoproject.com/en/2.0/topics/forms/formsets/

    还有一些变体,例如 model 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>
    

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

    【讨论】:

    • 感谢您的回复,我正在为餐厅构建一个解决方案,其中支票或发票将包含多个项目(三明治、饮料等),我有一个餐点模型和另一个模型发票项目,我想知道如何构建一个视图,使用户能够将许多项目添加到同一张发票。表单集是我想过的,但老实说我以前从未尝试过,但是如何在视图中使用它?
    • 查看编辑。它显示了基本概念。显然,这在多大程度上适合您的需求取决于您的应用程序将拥有的视图类型。它是基于函数的,因为它是我习惯的,但是将其更改为 CBV 应该是直接的。请注意,您可能需要某种 java / jquery 脚本来为您的表单集动态添加额外的表单,以便您可以添加订单。
    猜你喜欢
    • 2019-05-27
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 2012-05-26
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多