简体   繁体   English

django泛型CreateView和UpdateView中的Modelformset

[英]Modelformset in django generic CreateView and UpdateView

I have a model Organization with two fields 'id' and 'name'. 我有一个模型组织,有两个字段'id'和'name'。 I intend to populate it using dynamic model formsets.The code I have this far is as follows. 我打算用动态模型formsets填充它。我到目前为止的代码如下。

forms 形式

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

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

views 意见

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

template create 模板 创建

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

update 更新

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

However, both the create template and the update template display pre-existing organizations while this should only be happening in the update template. 但是,创建模板和更新模板都会显示预先存在的组织,而这只应在更新模板中进行。 Moreover, deleting pre-existing organizations in the update page returns the following error: 此外,在更新页面中删除预先存在的组织会返回以下错误:

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

I am new to django generic views and working with formsets. 我是django通用视图和使用formset的新手。 What I'm I doing wrong? 我做错了什么?

Thanks in advance. 提前致谢。

By default django model formsets will show any items that it can find from database. 默认情况下, django model formsets将显示它可以从数据库中找到的任何项目。 So you have to override the queryset parameter, when creating one, to let it know which items to use and when. 所以你必须在创建一个queryset参数时覆盖它,让它知道要使用哪些项目以及何时使用。 For example, you should provide - 例如,你应该提供 -

Organization.objects.none()

for your create view like this - 对于你这样的创建视图 -

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):
        ...

this will force the formset to render a blank form. 这将强制formset呈现一个空白表单。 Similarly change in update view to edit an specific item - 同样在更新视图中更改以编辑特定项目 -

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):
        ...

Hope this fixes your problem. 希望这可以解决您的问题。 If you still see the problem, then please update the question with details of urls and a possible screenshot. 如果您仍然看到问题,请更新问题以及网址和可能的屏幕截图。 I will see what I can do. 我会看到我能做什么。

Your post method returns nothing when formset is invalid in both Class based views (create and update), you should return form_invalid in else branch: 当两个基于类的视图(创建和更新)中的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