django 添加动态表格的方法

传统方法(基于方法的视图):http://stellarchariot.com/blog/2011/02/dynamically-add-form-to-formset-using-javascript-and-django/

概要:

     服务器端,使用了formset  , 文档在这里:https://docs.djangoproject.com/en/dev/topics/forms/formsets/

 

     客户端,使用脚本动态添加内容。

 

 

class based view ,参考这里:http://kevindias.com/writing/django-class-based-views-multiple-inline-formsets/

总结:

      重写了get/post方法。

      要点: 

         1. form里面做关联:

# forms.py

from django.forms import ModelForm

from django.forms.models import inlineformset_factory



from .models import Recipe, Ingredient, Instruction





class RecipeForm(ModelForm):

    class Meta:

        model = Recipe





IngredientFormSet = inlineformset_factory(Recipe, Ingredient)

InstructionFormSet = inlineformset_factory(Recipe, Instruction)

  2. 重写post/get方法,并在里面对子表初始化,注意get里面构造时无参,post里有参。

ingredient_form = IngredientFormSet()  vs  ingredient_form = IngredientFormSet(self.request.POST)

class RecipeCreateView(CreateView):

    template_name = 'recipe_add.html'

    model = Recipe

    form_class = RecipeForm

    success_url = 'success/'



    def get(self, request, *args, **kwargs):

        """

        Handles GET requests and instantiates blank versions of the form

        and its inline formsets.

        """

        self.object = None

        form_class = self.get_form_class()

        form = self.get_form(form_class)

        ingredient_form = IngredientFormSet()

        instruction_form = InstructionFormSet()

        return self.render_to_response(

            self.get_context_data(form=form,

                                  ingredient_form=ingredient_form,

                                  instruction_form=instruction_form))



    def post(self, request, *args, **kwargs):

        """

        Handles POST requests, instantiating a form instance and its inline

        formsets with the passed POST variables and then checking them for

        validity.

        """

        self.object = None

        form_class = self.get_form_class()

        form = self.get_form(form_class)

        ingredient_form = IngredientFormSet(self.request.POST)

        instruction_form = InstructionFormSet(self.request.POST)

        if (form.is_valid() and ingredient_form.is_valid() and

            instruction_form.is_valid()):

            return self.form_valid(form, ingredient_form, instruction_form)

        else:

            return self.form_invalid(form, ingredient_form, instruction_form)

  3. 保存时做关联:

ingredient_form.instance = self.object
   def form_valid(self, form, ingredient_form, instruction_form):

        """

        Called if all forms are valid. Creates a Recipe instance along with

        associated Ingredients and Instructions and then redirects to a

        success page.

        """

        self.object = form.save()

        ingredient_form.instance = self.object

        ingredient_form.save()

        instruction_form.instance = self.object

        instruction_form.save()

        return HttpResponseRedirect(self.get_success_url())

  4. 模板注意包含两个隐藏域:

                {{ ingredient_form.management_form }}

                {{ ingredient_form.non_form_errors }}

  

 3. 自己写了个demo,完整代码看这里: https://github.com/TommyU/dynamic_form/

 

你可能感兴趣的:(django)