• django批量form表单处理


    1.应用说明

      一般在表单信息录入中,如果存在许多重复提交的信息,我们就需要进行批量处理,比如学生信息的批量录入。

      这里一种方式就是使用xlrd模块处理,把学生信息录入到系统内

      另外一种方式就是采用我们from组件中提供的formset来进行批量处理,实现用户在同一页面提交多张表单

    2.相关源码

    formsets.py

    def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False,
                        can_delete=False, max_num=None, validate_max=False,
                        min_num=None, validate_min=False):
        """Return a FormSet for the given form class."""
        if min_num is None:
            min_num = DEFAULT_MIN_NUM
        if max_num is None:
            max_num = DEFAULT_MAX_NUM
        # hard limit on forms instantiated, to prevent memory-exhaustion attacks
        # limit is simply max_num + DEFAULT_MAX_NUM (which is 2*DEFAULT_MAX_NUM
        # if max_num is None in the first place)
        absolute_max = max_num + DEFAULT_MAX_NUM
        attrs = {'form': form, 'extra': extra,
                 'can_order': can_order, 'can_delete': can_delete,
                 'min_num': min_num, 'max_num': max_num,
                 'absolute_max': absolute_max, 'validate_min': validate_min,
                 'validate_max': validate_max}
        return type(form.__name__ + str('FormSet'), (formset,), attrs)

     该函数主要用来处理表单集

    3.批量添加案例

    models.py

    from django.db import models
    
    class User(models.Model):
        user = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
        email = models.CharField(max_length=32)

    urls.py

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^index/', views.index),
    ]

    viewspy

    from django.shortcuts import render,HttpResponse
    from django import forms
    from app01 import models
    
    """
    class UserForm(forms.Form):
        id = forms.CharField(required=True)
        user = forms.CharField(required=True)
        pwd = forms.CharField(required=True)
        email = forms.CharField(required=True)
    """
    # 简写版
    class UserForm(forms.ModelForm):
        class Meta:
            model = models.User
            fields ="__all__"
    
    def index(request):
        # 生成一个类,它是form集合。extra设置展示的表单数量
        UserFormSet = forms.formset_factory(UserForm,extra=3,)
        if request.method == 'GET':
            formset = UserFormSet()
            return render(request,"index.html",{'formset':formset})
    
        formset = UserFormSet(request.POST)
        if formset.is_valid():
            flag = False  # 标志位
            for row in formset.cleaned_data:
                if row:
                    # **表示将字典扩展为关键字参数
                    res = models.User.objects.create(**row)
                    if res:  # 判断返回信息
                        flag = True
    
            if flag:
                return HttpResponse('添加成功')
            else:
                return HttpResponse('添加失败')
    
        return render(request, "index.html", {'formset': formset})

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form method="post">
        {{ formset.management_form }}
        {% csrf_token %}
        <table border="1">
            <tr>
                <th>用户名</th>
                <th>密码</th>
                <th>邮箱</th>
            </tr>
            {% for form in formset %}
                <tr>
                    {% for field in form %}
                        <td>{{ field }} {{ field.errors.0 }} </td>
                    {% endfor %}
                </tr>
            {% endfor %}
        </table>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>

     效果:

    直接点击提交,返回添加失败,只添加一行数据,返回添加成功,添加部分数据:

    它会返回提示信息,填写完后查看数据库:

    4.批量修改案例

      这里其实在页面渲染出来数据,再进行修改在全部写入即可,当中获取它修改的表单id,以及使用initial方法

    在上面的基础上在做修改:

    views.py

    from django.shortcuts import render
    from django import forms
    from app01 import models
    
    
    class UserForm(forms.Form):
        id = forms.CharField(required=True)
        user = forms.CharField(required=True)
        pwd = forms.CharField(required=True)
        email = forms.CharField(required=True)
    
    
    def index(request):
        queryset = models.User.objects.all().values()
        UserFormSet = forms.formset_factory(UserForm,extra=0)
        if request.method == 'GET':
            #  initial 参数用来给 ModelForm 定义初始值
            formset = UserFormSet(initial=queryset)
            return render(request,'index.html',{'formset':formset})
    
        formset = UserFormSet(request.POST)
        if formset.is_valid():
            for row in formset.cleaned_data:
                # 删除字典携带的id
                id = row.pop('id')
                models.User.objects.filter(id=id).update(**row)
    
        return render(request, 'index.html', {'formset': formset})

     index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .hide{
                display: none;
            }
        </style>
    </head>
    <body>
        <form method="post">
            {{ formset.management_form }}
            {% csrf_token %}
            <table border="1">
                <tr>
                    <th>用户名</th>
                    <th>密码</th>
                    <th>邮箱</th>
                </tr>
                {% for form in formset %}
                <tr>
                    {% for field in form %}
                        {% if forloop.first %}
                            <td class="hide">{{ field }} </td>
                        {% else %}
                            <td>{{ field }} {{ field.errors.0 }} </td>
                        {% endif %}
                    {% endfor %}
                </tr>
                {% endfor %}
            </table>
            <input type="submit" value="提交">
        </form>
    </body>
    </html>

     效果还是和上面案例一样,我们对于某个字段做修改:

    提交至数据库

    # 这里更新的时候,需要使用到id,但是它不需要在表单中显示出来,所以我们在html中对它做了隐藏处理

    # 至于为什么这里不是用forms.ModelForm而是使用forms.Form,是因为ModelForm默认的全部字段中没有包含id

  • 相关阅读:
    Beta冲刺——星期四
    Beta冲刺——星期三
    团队学期总结
    Beta版本发布
    第三天Beta冲刺
    第二天Beta冲刺
    第一天Beta冲刺
    个人作业——Alpha项目测试
    第四次团队作业
    第三次团队作业
  • 原文地址:https://www.cnblogs.com/LearningOnline/p/9546626.html
Copyright © 2020-2023  润新知