簡體   English   中英

django泛型CreateView和UpdateView中的Modelformset

[英]Modelformset in django generic CreateView and UpdateView

我有一個模型組織,有兩個字段'id'和'name'。 我打算用動態模型formsets填充它。我到目前為止的代碼如下。

形式

class OrganizationForm(forms.ModelForm):
    class Meta:
        model = Organization
        fields = ('name',)

OrganizationFormset = modelformset_factory(Organization, form=OrganizationForm, fields=('name', ), extra=1)

意見

class OrganizationCreate(CreateView):
    model = Organization
    form_class = OrganizationForm

    def get_context_data(self, **kwargs):
        context = super(OrganizationCreate, self).get_context_data(**kwargs)
        context['formset'] = OrganizationFormset()
        return context

    def post(self, request, *args, **kwargs):
        formset = OrganizationFormset(request.POST)
        if formset.is_valid():
            return self.form_valid(formset)

    def form_valid(self, formset):
        formset.save()
        return HttpResponseRedirect('/')

    def form_invalid(self, formset):
        return self.render_to_response(self.get_context_data(formset=formset))


class OrganizationUpdate(UpdateView):
    model = Organization
    form_class = OrganizationForm
    template_name_suffix = '_update_form'

    def get_context_data(self, **kwargs):
        context = super(OrganizationUpdate, self).get_context_data(**kwargs)
        context['formset'] = OrganizationFormset()
        return context

    def post(self, request, *args, **kwargs):
        formset = OrganizationFormset(request.POST)
        if formset.is_valid():
            return self.form_valid(formset)

    def form_valid(self, formset):
        formset.save()
        return HttpResponseRedirect('/')

    def form_invalid(self, formset):
        return self.render_to_response(self.get_context_data(formset=formset))

模板 創建

<form id="myForm" method="post" action="">
            {% csrf_token %}
            {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %}
           {{ form }}
           <table border="0" cellpadding="0" cellspacing="0">
               <tbody>
                   {% for form in formset.forms %}
                   {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %}
                   <tr>
                      <td>
                         {% if form.instance.pk %}{{ form.DELETE }}{% endif %}

                         {{ form.field1 }}
                      </td>
                      <td>{{ form.name }}</td>
                   </tr>
                   {% endfor %}
               </tbody>
           </table>
           {{ formset.management_form }}
            <input type="submit" value="Create Location">
       </form>

更新

<form id="myForm" method="post" action="">
            {% csrf_token %}

           <table border="0" cellpadding="0" cellspacing="0">
               <tbody>
                   {% for form in formset.forms %}
                   {% for hidden in form.hidden_fields %} {{ hidden }} {% endfor %}
                   <tr>
                      <td>
                         {% if form.instance.pk %}{{ form.DELETE }}{% endif %}

                         {{ form.field1 }}
                      </td>
                      <td>{{ form.name }}</td>
                   </tr>
                   {% endfor %}
               </tbody>
           </table>
           {{ formset.management_form }}
            <input type="submit" value="Update organizations">
       </form>

但是,創建模板和更新模板都會顯示預先存在的組織,而這只應在更新模板中進行。 此外,在更新頁面中刪除預先存在的組織會返回以下錯誤:

The view aims.views.OrganizationUpdate didn't return an HttpResponse object. It returned None instead.

我是django通用視圖和使用formset的新手。 我做錯了什么?

提前致謝。

默認情況下, django model formsets將顯示它可以從數據庫中找到的任何項目。 所以你必須在創建一個queryset參數時覆蓋它,讓它知道要使用哪些項目以及何時使用。 例如,你應該提供 -

Organization.objects.none()

對於你這樣的創建視圖 -

class OrganizationCreate(CreateView):
    ...

    def get_context_data(self, **kwargs):
        ...
        context['formset'] = OrganizationFormset(queryset=Organization.objects.none()) # providing none

    def post(self, request, *args, **kwargs):
        ...

    def form_valid(self, formset):
        ...

    def form_invalid(self, formset):
        ...

這將強制formset呈現一個空白表單。 同樣在更新視圖中更改以編輯特定項目 -

class OrganizationUpdate(UpdateView):
    ...

    def get_context_data(self, **kwargs):
        context = super(OrganizationUpdate, self).get_context_data(**kwargs)
        context['formset'] = OrganizationFormset(queryset=Organization.objects.get(pk=< get the pk from url when editing>))
        return context

    def post(self, request, *args, **kwargs):
        ...

    def form_valid(self, formset):
        ...

    def form_invalid(self, formset):
        ...

希望這可以解決您的問題。 如果您仍然看到問題,請更新問題以及網址和可能的屏幕截圖。 我會看到我能做什么。

當兩個基於類的視圖(創建和更新)中的formset無效時,你的post方法什么都不返回,你應該在else分支中返回form_invalid

if formset.is_valid():
    return self.form_valid(formset)
else:
    return self.form_invalid(formset)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM