Django Formset:如何仅向表中添加行? [英] Django Formset: How to add lines only to my table?

查看:47
本文介绍了Django Formset:如何仅向表中添加行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试向表单添加表单集,以便能够向帐单添加行.我开始使用通用视图,因为我发现本教程可以使用表单集:

I am trying to add a formset to a forms in order to be able to add lines to a bill. I`ve start using a generic view as I found this tutorial for working with formset: https://dev.to/zxenia/django-inline-formsets-with-class-based-views-and-crispy-forms-14o6

如何修改代码以仅向模板中添加行:create_bill.html

How can I modify my code to only add lines to my template: create_bill.html

我试图将以下代码添加到我的表{{form.lines | as_crispy_field}}中,但是没有用.

I`ve tried to add the following code to my table {{ form.lines|as_crispy_field }} to my table but it did not work.

非常感谢

views.py

@login_required(login_url="/login/")
class BillCreate(CreateView):
    model = Bill
    template_name = 'accounting/bills/create_bill.html'
    form_class = BillForm
    success_url = None

    def get_context_data(self, **kwargs):
        data = super(BillCreate, self).get_context_data(**kwargs)
        if self.request.POST:
            data['lines'] = BillLineFormSet(self.request.POST)
        else:
            data['lines'] = BillLineFormSet()
        return data

    def form_valid(self, form):
        context = self.get_context_data()
        lines = context['lines']
        with transaction.atomic():
            form.instance.created_by = self.request.user
            self.object = form.save()
            if lines.is_valid():
                lines.instance = self.object
                lines.save()
        return super(BillCreate, self).form_valid(form)

    def get_success_url(self):
        return reverse_lazy('accounting:bill_detail', kwargs={'pk': self.object.pk})

models.py

class Bill(models.Model):
    vendor = models.CharField(max_length=250, null=True, blank=True)
    bill_title = models.CharField(max_length=250, null=True, blank=True)
    reference = models.CharField(max_length=250, null=True, blank=True)

class BillLine(models.Model):
    bill = models.ForeignKey(Bill,related_name="has_lines",on_delete=models.CASCADE, blank=True, null=True, unique=False)
    bill_item = models.CharField(max_length=100, verbose_name="Line")
    description = models.TextField(blank=True, null=True)

forms.py

class BillForm(forms.ModelForm):

    class Meta:
        model = Bill
        fields = ['bill_title','vendor','reference']  


    def __init__(self, *args, **kwargs):
        super(BillForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_tag = True
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-md-3 create-label'
        self.helper.field_class = 'col-md-9'
        self.helper.layout = Layout(
            Div(
                Field('bill_title'),
                Field('vendor'),
                Fieldset('Add lines',
                    Formset('lines')),
                Field('reference'),
                HTML("<br>"),
                ButtonHolder(Submit('submit', 'save')),
                )
            )

class BillLineForm(forms.ModelForm):

    class Meta:
        model = BillLine
        exclude = ()

BillLineFormSet = inlineformset_factory(
    Bill, BillLine, form=BillLineForm,
    fields=['bill_item', 'description'], extra=1, can_delete=True
    )

custom_layout_object.py

from crispy_forms.layout import LayoutObject, TEMPLATE_PACK
from django.shortcuts import render
from django.template.loader import render_to_string

class Formset(LayoutObject):
    template = "accounting/bills/formset.html"

    def __init__(self, formset_name_in_context, template=None):
        self.formset_name_in_context = formset_name_in_context
        self.fields = []
        if template:
            self.template = template

    def render(self, form, form_style, context, template_pack=TEMPLATE_PACK):
        formset = context[self.formset_name_in_context]
        return render_to_string(self.template, {'formset': formset})

urls.py

path('bill/create/', views.BillCreate, name='bill_create'),

create_bill.html

{% load crispy_forms_tags %}

{% block content %}
<div class="container">
    <div class="card">
        <div class="card-header">
            Create bill
        </div>
        <div class="card-body">
             <div class="card-block table-border-style">
                 <div class="table-responsive">
                     <table class="table table-hover">
                         <thead>
                            <tr>
                              <th class="center">Item</th>                                                    
                               <th>Description</th>
                               <th class="center">Qty</th>
                               <th class="right">Price</th>
                               <th>Account</th>
                               <th>Tax Rate</th>
                               <th class="right">Amount</th>
                             </tr>
                            </thead>
                            <tbody>
                             <tr>                                                                                                   
                               <td class="center"></td>
                               <td class="left strong"></td>
                               <td class="left"></td>
                               <td class="right"></td>
                               <td class="right"></td>
                               <td class="center"></td>
                               <td class="right"></td>
                              </tr>
                               <tr>                                                                                                 
                               <td class="center"></td>
                               <td class="left strong"></td>
                               <td class="left"></td>
                               <td class="right"></td>
                               <td class="right"></td>
                               <td class="center"></td>
                               <td class="right"></td>
                              </tr>
                              {{ formset.management_form }}
                                 {% for form in formset.forms %}
                                     {{ form.lines|as_crispy_field }}
                                 {% endfor %}
                                                                                        
                              </tbody>
                      </table>
                 </div>
             </div> 
        </div>
    </div>
</div>
{% endblock content %}

formset.html

{% load crispy_forms_tags %}
<table>
{{ formset.management_form|crispy }}

    {% for form in formset.forms %}
            <tr class="{% cycle 'row1' 'row2' %} formset_row-{{ formset.prefix }}">
                {% for field in form.visible_fields %}
                <td>
                    {# Include the hidden fields in the form #}
                    {% if forloop.first %}
                        {% for hidden in form.hidden_fields %}
                            {{ hidden }}
                        {% endfor %}
                    {% endif %}
                    {{ field.errors.as_ul }}
                    {{ field|as_crispy_field }}
                </td>
                {% endfor %}
            </tr>
    {% endfor %}

</table>
<br>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js">
</script>
<script src="{% static 'assets/js/jquery.formset.js' %}">
</script>
<script type="text/javascript">
    $('.formset_row-{{ formset.prefix }}').formset({
        addText: 'add another',
        deleteText: 'remove',
        prefix: '{{ formset.prefix }}',
    });
</script>

推荐答案

我仅使用{%crispy.form%}

I`ve resolved it by just using {% crispy.form %}

这篇关于Django Formset:如何仅向表中添加行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆