多个Formset无效的UpdateView

时间:2015-11-02 02:15:18

标签: python django django-class-based-views inline-formset

我尝试根据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来动态添加和删除表单集中的表单 谢谢

0 个答案:

没有答案