我下面具有多对多关系的模型Entry
和Meaning
。我需要创建一个更新表单/视图来同时编辑Entry
和Meaning
对象。我还必须能够在编辑Meaning
对象时将更多的Entry
对象添加到UpdateView
对象中。
我尝试如下使用modelformset_factory
和Meaning
。
我可以看到表单,但是我的视图没有保存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)