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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM