将表单集保存在 UpdateView 中

msa*_*aio 3 python django django-forms django-views django-generic-views

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

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

  1. 我如何保存Meaning更改?

  2. 如何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)
Run Code Online (Sandbox Code Playgroud)

形式

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

MeaningFormSet = modelformset_factory(models.Meaning, fields=('title', 'language'))
Run Code Online (Sandbox Code Playgroud)

看法

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
Run Code Online (Sandbox Code Playgroud)

模板

# 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>
Run Code Online (Sandbox Code Playgroud)

msa*_*aio 5

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)
Run Code Online (Sandbox Code Playgroud)