Django Formset:如何仅向表中添加行? [英] Django Formset: How to add lines only to my table?
问题描述
我正在尝试向表单添加表单集,以便能够向帐单添加行.我开始使用通用视图,因为我发现本教程可以使用表单集:
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屋!