Save formset in an UpdateView

泪湿孤枕 提交于 2021-01-01 06:45:06

问题


I have the models Entry and Meaning below with many-to-many relation. I need to create an update form/view to edit Entry and Meaning objects at the same time. I have also to be able to add more Meaning objects to an Entry object while editing it. I tried to use UpdateView and modelformset_factory as below.

I can see the forms, but my view doesn't save the Meaning changes. I have two questions:

  1. How do I save the Meaning changes?

  2. How do I add or delete a Meaning object in this form/view?

Models

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)

Forms

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

MeaningFormSet = modelformset_factory(models.Meaning, fields=('title', 'language'))

View

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

Template

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


I solved the problem adding the post method to EntryUpdateView class:

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)


来源:https://stackoverflow.com/questions/45841951/save-formset-in-an-updateview

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!