是否有一种简单的方法来显示包含两个相关模型的表单?请在models.py文件中考虑这些:
class InvoiceList(models.Model):
invoice_number = models.IntegerField(default=0)
recipient = models.CharField(max_length=100)
class InvoiceItem(models.Model):
item_description = models.CharField(max_length=150)
list = models.ForeignKey(InvoiceList)
基本上,每张发票都可以有一个或多个发票项目。
forms.py:
class InvoiceListForm(ModelForm):
class Meta:
model = InvoiceList
fields = ['invoice_number', 'recipient']
class InvoiceItemForm(ModelForm):
class Meta:
model = InvoiceItem
exclude = ('list',)
fields = ['item_description']
我的问题出在views.py
中def update_edit(request, invoice_id):
a = get_object_or_404(InvoiceList, pk=invoice_id)
form = InvoiceListForm(instance=a)
formset = InvoiceItemForm(instance=a)
return render(request, 'file.html', {'invoice_info': form, 'items': formset})
file.html
<h1>Something Something Invoice</h1>
<form action="." name="stock_details" method="post">
{% csrf_token %}
{{ invoice_info.as_p }}
{% for item in items %}
{{ item.as_table }}<br>
{% endfor %}
</form>
以上并不完全有效。它显示invoice_info,但不显示项目。我确定这与实例调用错误的东西有关。有人可以帮忙吗?谢谢!
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
#This view is the main page when loaded
url(r'^$', views.index, name='index'),
#This view is when viewing the details
url(r'^invoice/(?P<invoice_id>[0-9]+)/$', views.detail, name='detail'),
#This view is when doing some function
url(r'^add_new_invoice/$', views.add_new, name='add_new'),
#This view is to delete an invoice
url(r'^delete/(?P<invoice_id>[0-9]+)/$', views.delete, name='delete'),
#This view is to update an invoice
url(r'^update/(?P<invoice_id>\d+)/(?P<item_id>\d+)/$', views.update_edit, name='update_edit'),
]
index.html(这是列出发票的地方)
{% if latest_invoice_list %}
<h1>Invoices</h1><br>
<table border=1>
<tr>
<td width=50 align="center">Invoice Number</td>
<td width=200 align="center">Recipient</td>
<td align="center">Update/Resend</td>
<td align="center">Delete</td>
</tr>
{% for invoice in latest_invoice_list %}
<tr>
<td align="center">{{ invoice.invoice_number }}</td>
<td align="center"><a href="/invoice/{{ invoice.id }}/">{{ invoice.recipient }}</a></td>
<td align="center"><form action="{% url 'update_edit' invoice.id invoice.item_id %}" name="update" method="post" valign="bottom">{% csrf_token %}<input type="submit" value="Update"></form></td>
<td align="center"><form action="{% url 'delete' invoice.id %}" name="delete" method="post" valign="bottom">{% csrf_token %}<input type="submit" value="Delete"></form></td>
</tr>
{% endfor %}
</table>
<a href="{% url 'add_new' %}">Create a new invoice</a>
{% else %}
<p>No stocks were added. <a href="{% url 'add_new' %}">Create a new invoice now!</a></p>
{% endif %}
答案 0 :(得分:0)
我认为你应该{{ items.as_table }}
而不是你做的for
循环。
同时添加前缀,因为它们位于同一HTML表单上,这将使数据知道它属于哪种形式
有关前缀的更多信息,请访问:https://docs.djangoproject.com/en/1.9/ref/forms/api/#prefixes-for-forms
修改强>
您正在尝试为InvoiceList
和InvoiceListForm
使用InvoiceItemForm
模型的实例,这样做无效。
由于您正在编辑它们,因此最好在网址中包含item_id
,然后从中获取InvoiceItem
的实例
def update_edit(request, invoice_id, item_id):
a = get_object_or_404(InvoiceList, pk=invoice_id)
i = get_object_or_404(InvoiceItem, pk=item_id)
form = InvoiceListForm(instance=a, prefix="list")
formset = InvoiceItemForm(instance=i, prefix="item")
return render(request, 'file.html', {'invoice_info': form, 'items': formset})
或只需包含item_id
,然后从中获取外键中的InvoiceList
实例。
def update_edit(request, item_id):
i = get_object_or_404(InvoiceItem, pk=item_id)
form = InvoiceListForm(instance=i.list, prefix="list")
formset = InvoiceItemForm(instance=i, prefix="item")
return render(request, 'file.html', {'invoice_info': form, 'items': formset})
答案 1 :(得分:0)
好的,所以我设法通过使用inlineformset_factory来解决它,但放在forms.py文件中。所以这是以防任何人都在寻找它:
forms.py
# Added this new line at the top
from django.forms.models import inlineformset_factory
# Placed this at the very bottom
InvoiceFormSet = inlineformset_factory(InvoiceList, InvoiceItem, fields=('item_description',), extra=0)
views.py
# Added this line at the top
from .forms import InvoiceFormSet
# Adjusted the def to this
def update_edit(request, invoice_id):
# Confirm and acquire the stuff from the main model
a = get_object_or_404(InvoiceList, pk=invoice_id)
# Acquire the related model stuff under the main model & assign to "b"
b = InvoiceFormSet(instance=a, prefix="item")
# Acquire the stuff from the main model & assign to "form"
form = InvoiceListForm(instance=a, prefix="list")
return render(request, 'file.html', {'invoice_info': form, 'items': b})
file.html
<h1>Something Something Invoice</h1>
<form action="." name="stock_details" method="post">
{% csrf_token %}
{{ invoice_info.as_p }}
{% for item in items %}
{{ item.as_table }}<br>
{% endfor %}
</form>
项目中的&#34;项目&#34;现在也工作,可以通过这种方式迭代内容。奇怪的是,有一个&#34;删除&#34;单独出现的复选框。