django批量form表单处理

枫铃3年前 (2021-07-10)Python227

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

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

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

2.相关源码

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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># 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

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。