zoukankan      html  css  js  c++  java
  • 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/
  • 相关阅读:
    基于红帽5裁剪一个简单的Linux
    Linux系统初始化流程
    bash学习记录
    ubuntu 上安装MySQL
    Effective Modern C++ 条款4:掌握查看型别推导结果的方法
    Effective Modern C++ 条款3:理解decltype
    ubuntu 环境下向GitHub上传(push)每次都需要用户名密码问题
    Effective Modern C++ 条款2:理解auto型别推导
    Effective Modern C++  条款1:理解模板型别推导
    ubuntu16.04环境编译gSOAP
  • 原文地址:https://www.cnblogs.com/Tommy-Yu/p/3928084.html
Copyright © 2011-2022 走看看