2016-02-28 52 views
0

有兩種相關模型顯示錶單的簡單方法嗎?在models.py文件考慮這些:如何從兩個相關模型中顯示formset?

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

是的,我確實意識到def是非常裸露的視圖。一旦我得到它基本上工作,我會填寫與適當的檢查。 – Bob

回答

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}) 

文件。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> 

「項目中的項目」現在也可以工作,可以遍歷內容。奇怪的是,有一個自己出現的「刪除」複選框。

0

我認爲你應該做的{{ items.as_table }}代替for循環你沒有。

還加入了前綴,因爲它們是相同的HTML表單將數據知道哪種形式屬於

更多關於前綴這裏:https://docs.djangoproject.com/en/1.9/ref/forms/api/#prefixes-for-forms

編輯

你試圖對InvoiceListFormInvoiceItemForm使用InvoiceList模型的實例,這將不起作用。

既然你編輯他們兩個,最好在URL中inlcude的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}) 
+0

謝謝。不幸的是,「項目」的內容仍爲空,但前綴確實出現在ID中。 – Bob

+0

我做了一個編輯答案,我希望它有幫助。 – eustass

+0

再次感謝@ kushtrimh!第一個解決方案不起作用,我不知道如何調整URL中的正則表達式來實現invoice_id和item_id。 第二種解決方案顯示了一些內容,但並不完全正確。我必須在urls.py中將「invoice_id」更改爲「item_id」才能使其正常工作。沒有這個,它會發出一個「意外的關鍵字參數invoice_id」。 更改後,它排序反轉顯示。例如:發票A(1,2,3 ...)和發票B(1,2,3 ...)。查看清單中的第一張發票(id = 1),顯示InvoiceA(1)。查看清單中的第二張發票(id = 2),顯示InvoiceA(2)。 – Bob

相關問題