我下面具有多对多关系的模型EntryMeaning。我需要创建一个更新表单/视图来同时编辑EntryMeaning对象。我还必须能够在编辑Meaning对象时将更多的Entry对象添加到UpdateView对象中。
我尝试如下使用modelformset_factoryMeaning

我可以看到表单,但是我的视图没有保存Meaning更改。我有两个问题:


如何保存Meaning更改?
如何在此表单/视图中添加或删除对象?


楷模

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>

最佳答案

我解决了将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)

09-19 06:04