在UpdateView中保存formset

时间:2017-08-23 14:03:01

标签: python django django-forms django-views django-generic-views

下面的模型EntryMeaning具有多对多关系。我需要创建一个更新表单/视图,以便同时编辑EntryMeaning个对象。我还可以在编辑时向Meaning对象添加更多Entry个对象。 我尝试使用UpdateViewmodelformset_factory,如下所示。

我可以看到表单,但我的观点并没有保存Meaning更改。我有两个问题:

  1. 如何保存Meaning更改?

  2. 如何在此表单/视图中添加或删除Meaning个对象?

  3. 模型

    class Entry(models.Model):
        title = models.CharField(max_length=70)
        slug = models.SlugField('slug', max_length=100, unique=True)
    
    class Meaning(models.Model):
        title = models.CharField(max_length=70)
        language = models.CharField(max_length=5, choices=LANGUAGE_CHOICES)
        entry = models.ManyToManyField(
            Entry, related_name='meaning', 
            related_query_name='meanings',
            through='MeaningRelation')
    
    class MeaningRelation(models.Model):
        entry = models.ForeignKey(Entry, on_delete=models.CASCADE)
        meaning = models.ForeignKey(Meaning, on_delete=models.CASCADE)
    

    表单

    class EntryForm(forms.ModelForm):
        class Meta:
            model = models.Entry
            fields = ['title', 'slug']
    
    MeaningFormSet = modelformset_factory(models.Meaning, fields=('title', 'language'))
    

    视图

    class EntryUpdateView(UpdateView):
        model = models.Entry
        form_class = forms.EntryForm
        formset_class = forms.MeaningFormSet
        template_name = 'edit.html'
    
        def get_context_data(self, **kwargs):
            context = super(EntryUpdateView, self).get_context_data(**kwargs)
            qs = models.Meaning.objects.filter(entry=self.get_object())
            formset = forms.MeaningFormSet(queryset=qs)
            context['meaning_formset'] = formset
            return context
    

    模板

    # edit.html
    <form action="" method="post">
        {% csrf_token %}
        {{ form.as_table }}
    
        {{ meaning_formset.management_form }}
        {% for meaning_form in meaning_formset %}
            {{ meaning_form.as_p }}
            <hr>
        {% endfor %}
    
        <input type="submit" value="Update"/>
    </form>
    

1 个答案:

答案 0 :(得分:2)

我解决了将post方法添加到EntryUpdateView类:

的问题
def post(self, request, *args, **kwargs):
    self.object = self.get_object()
    form_class = self.get_form_class()
    form = self.get_form(form_class)
    qs = models.Meaning.objects.filter(entry=self.get_object())
    formsets = forms.MeaningFormSet(self.request.POST, queryset=qs)

    if form.is_valid():
        for fs in formsets:
            if fs.is_valid():
                fs.save()
        return self.form_valid(form)
    return self.form_invalid(form)