我尝试根据this tutorial中提供的CreateView为与其他2个模型具有泛型关系的模型创建通用UpdateView。 表单和表单集按预期填充,但是当我保存时,我会被重定向到模型详细信息页面,并且不会保存更改。
我的问题类似于this one,但提供的建议没有帮助,因为它们特定于前一个问题。
这是我的代码:
# models.py
class Ingredient(models.Model):
...
content_type = models.ForeignKey(ContentType, editable=False)
object_id = models.PositiveIntegerField(editable=False)
content_object = GenericForeignKey()
class Step(models.Model):
Same as Ingredient
class Recipe(models.Model):
...
ingredients = generic.GenericRelation(Ingredient)
steps = generic.GenericRelation(Step)
# forms.py
class RecipeForm(forms.ModelForm):
class Meta:
model = Recipe
IngredientFormSet = generic_inlineformset_factory(Ingredient, extra=1)
StepFormSet = generic_inlineformset_factory(Step, extra=1)
# views.py
class RecipeUpdate(UpdateView):
model = Recipe
form_class = RecipeForm
template_name = 'app_recipes/recipe_add.html'
def get(self, request, *args, **kwargs):
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
ingredient_form = IngredientFormSet(instance = self.object)
step_form = StepFormSet(instance = self.object)
return self.render_to_response(self.get_context_data(
form=form,
ingredient_form=ingredient_form,
step_form=step_form))
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
ingredient_form = IngredientFormSet(self.request.POST, instance=self.object)
step_form = StepFormSet(self.request.POST, instance=self.object)
if (form.is_valid() and ingredient_form.is_valid() and step_form.is_valid()):
return self.form_valid(form, ingredient_form, step_form)
else:
return self.form_invalid(form, ingredient_form, step_form)
def form_valid(self, form, ingredient_form, step_form):
self.object = form.save()
ingredient_form.instance = self.object
ingredient_form.save()
step_form.instance = self.object
step_form.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, ingredient_form, step_form):
return self.render_to_response(self.get_context_data(
form=form,
ingredient_form=ingredient_form,
step_form=step_form))
def get_success_url(self):
return reverse('recipe_detail', kwargs={'pk': self.object.pk})
我使用的是CreateView使用的相同模板:
...
<script src="{{ STATIC_URL }}js/jquery.formset.js"></script> # django-dynamic-formset
<script type="text/javascript">
$(function() {
$(".inline.{{ ingredient_form.prefix }}").formset({
prefix: "{{ ingredient_form.prefix }}",
})
$(".inline.{{ step_form.prefix }}").formset({
prefix: "{{ step_form.prefix }}",
})
})
</script>
...
<form action="." method="post">
{% csrf_token %}
<div>
{{ form.as_p }}
</div>
<fieldset>
<legend>Recipe Ingredients</legend>
{{ ingredient_form.management_form }}
{{ ingredient_form.non_form_errors }}
{% for form in ingredient_form %}
{{ form.id }}
<div class="inline {{ ingredient_form.prefix }}">
{% for field in form.visible_fields %}
<div>
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
</div>
{% endfor %}
</fieldset>
<fieldset>
<legend>Recipe Steps</legend>
{{ step_form.management_form }}
{{ step_form.non_form_errors }}
{% for form in step_form %}
{{ form.id }}
<div class="inline {{ step_form.prefix }}">
{% for field in form.visible_fields %}
<div>
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
</div>
{% endfor %}
</fieldset>
<input type="submit" value="Add recipe" class="submit" />
</form>
...
注意:我在模板中使用django-dynamic-formset来动态添加和删除表单集中的表单 谢谢