Django进阶-Forms模块实例

form验证实例

创建项目
django-admin startproject Mydjango
cd Mydjango
python manage.py startapp APP
项目架构

[其它保持默认的忽略未显示]

Mydjango
    APP
        migrations
            0001_initial.py
            __init__.py
        static
            __init__.py
            jquery-3.3.1.min.js
        templates
            add_user.html
            edit_user.html
            user.html
        admin.py
        apps.py
        models.py
        views.py
    Mydjango
        settings.py
        urls.py
    db.sqlite3
add_user.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this from login</title>
    <script src="../static/jquery-3.3.1.min.js"></script>
    <style>
        form i {
            color: red;
        }
        form span {}
        #id_gen li{list-style: none; }
    </style>
</head>
<body>
<h1>这是添加用户的页面</h1>
<!--加novalidata参数避免浏览器检测  加enctype是上传文件用-->
<form action="add_user.html" method="POST" novalidate enctype="multipart/form-data">
    {% csrf_token %}
    <!--解释说明:-->
    <!--HTML页面生成-->
    <!--{{ obj.user }} 从后端数据调取,利用 forms 模块生成 user用户 input标签 其它标签类同-->
    <!--错误信息反馈-->
    <!--{{ data_obj }} 为传送到后端的所有数据-->
    <!--{{ data_obj.user }} 为传送到后端,user 字段的数据-->
    <!--{{ data_obj.user.cleaned_data }} 为传送到后端,user 字段验证通过的数据-->
    <!--{{ data_obj.user.cleaned_errors }} 为传送到后端,user 字段验证失败的错误信息反馈,可能有多个错误信息-->
    <!--{{ data_obj.user.cleaned_errors.0 }} 为传送到后端,user 字段验证失败的错误信息反馈的第一个错误信息-->
    <!--其它字段类同-->
    <p>{{ data_obj.user.label }}:{{ data_obj.user }}<i>{{ data_obj.user.errors.0 }}</i></p>
    <p>{{ data_obj.pwd.label }}:{{ data_obj.pwd }}<i>{{ data_obj.pwd.errors.0 }}</i></p>
    <p>{{ data_obj.gen.label }}:{{ data_obj.gen }}</p>
    <p>{{ data_obj.area.label }}:{{ data_obj.area }}</p>
    <p>{{ data_obj.age.label }}:{{ data_obj.age }}<i>{{ data_obj.age.errors.0 }}</i></p>
    <p>{{ data_obj.email.label }}:{{ data_obj.email }}<i>{{ data_obj.email.errors.0 }}</i></p>
    <p>{{ data_obj.img.label }}{{ data_obj.img }}<i>{{ data_obj.img.errors.0 }}</i></p>
    <span>整体错误信息提示:{{ data_obj.non_field_errors }}</span>
    <!-- 后端数据全部以P标签形式生成,可以用 {{ obj.as_p }} 【不建议使用全部生成,不便于页面控制和样式修改】 -->
    <p><a><input type="submit" value="提交"></a></p>
</form>
<script>
    //所有关于密码的标签类型都变更为 passwors 输入时候密码密文显示 
    $("p").find("input[name='pwd']").attr("type", "password")
</script>
</body>
</html>
edit_user.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this from login</title>
    <script src="../static/jquery-3.3.1.min.js"></script>
    <style>
        p {display: block;width: 240px; }
        form li{list-style-type: none;}
        .errorlist li{color: red; position: absolute;left: 260px;}
    </style>
</head>
<body>
<h1>这是编辑中的页面</h1>
<!--加novalidata参数避免浏览器检测-->
{% csrf_token %}
<form action="/edit_user-{{ nid }}.html" method="POST" novalidate>
    <!--解释说明:-->
       <!--字段信息大部分和添加页面一样,在这里为了展示效果使用添加页面说明过的,一键生成 <p> 标签-->
    <!--其它字段类同-->
    {{ data_obj.as_p }}
    <input type="submit" value="提交">
</form>
</body>
</html>
users.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>this is user list</title>
    <script src="../static/jquery-3.3.1.min.js"></script>
    <style>
        a{cursor:pointer}
        table{border:solid 2px #0D3349; text-align: center;}
        table tr th {background: #0099CC;color:#fff; padding: 10px;font-size: 18px;}
        table tr td {background: #49b5ff;color:#fff; padding: 10px;}

    </style>
</head>
<body>
    <table id="User_Tab">                    <!--定义表格基本属性-->
        {% csrf_token %}
        <thead>                                                                       <!--表格标题标签-->
        <tr>
            <th>序列号</th>
            <th>用户名</th>
            <th>密码</th>
            <th>性别</th>
            <th>地区</th>
            <th>年龄</th>
            <th>邮箱</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
            {% for row in user_list %}
                <tr>
                    <td>{{ row.id }}</td>
                    <td>{{ row.user }}</td>
                    <td>{{ row.pwd }}</td>
                    {% if row.gen == True %}
                        <td>女</td>
                    {% else %}
                        <td>男</td>
                    {% endif %}
                    {% if row.area == "0" %}
                        <td>华南</td>
                    {% elif row.area == "1" %}
                        <td>华北</td>
                    {% elif row.area == "2" %}
                        <td>华中</td>
                    {% elif row.area == "3" %}
                        <td>华东</td>
                    {% else %}
                        <td>华西</td>
                    {% endif %}
                    <td>{{ row.age }}</td>
                    <td>{{ row.email }}</td>
                    <td><a href="edit_user-{{ row.id }}.html" type="submit">编辑</a>|<a onclick="del_user('{{ row.id }}')">删除</a></td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
<script>
    function del_user(nid) {
        var PostData = {};                          //建立空数组,用于存放拿到的数据
        PostData["nid"]=nid;                        //需要删除的数据添加到数组中便于传输到后端处理
        $.ajax({
            url: '/del_user.html',
            type: "GET",
            data: PostData,
            success: function (arg) {
                window.location.reload();           //刷新页面,显示刚添加信息
                }
                })
    }
</script>
</body>
</html>
models.py
# -*- coding:utf8 -*-
from django.db import models

class User_tab(models.Model):                 #创建用户表
    user = models.CharField(max_length=18,)          #用户字段
    pwd = models.CharField(max_length=32,)           #密码字段
    gen = models.BooleanField()                      #性别字段
    area = models.CharField(max_length=18,)          #地区字段
    age = models.IntegerField()                      #年龄字段
    email = models.EmailField()                      #邮箱字段
views.py
# -*- coding:utf8 -*-
from django.shortcuts import render,redirect,HttpResponse
from APP import models
from django import forms
from django.forms import fields,widgets
from django.core.exceptions import ValidationError

class From_check(forms.Form):              #继承forms模块
    #利用froms模块进行数据验证,变量名和前端name属性保持一致

# start ---------------------------------  forms模块数据验证  ------------------------------
    #            【注意,验证字段为了写入数据库方便,需要和数据库中数据字段保持一致!】

    # 限制类型-字符串最大长度最小长度,且不能为空
    user = fields.CharField(
        label="用户",
        max_length=18,
        min_length=2,
        required=True,
        error_messages={
            'required':'用户名不能为空',
            'max_length':'用户名不能超过18个字符',
            'min_length':'用户名不能小于2个字符',
        }
    )
    # 限制类型-字符串最小长度为8,且不能为空
    pwd = fields.CharField(
        label="密码",
        max_length=32,
        min_length=8,
        required=True,
        error_messages = {
        'required': '密码不能为空',
        'max_length': '密码不能超过32个字符',
        'min_length': '密码不能小于8个字符',
        }
    )
    gen = fields.ChoiceField(
        label="性别",
        choices=((0,'男'),(1,'女'),),
        initial=0,
        widget=widgets.RadioSelect,
        error_messages={
            'required': '性别是必选项'
        }
                 )
    area = fields.ChoiceField(
        label="地区",
        choices=[(0,'华南'),(1,'华北'),(2,'华中'),(3,'华东'),(4,'华西')],
        #如果从数据库中获取choices必须是列表格式,示例写法:【也可以使用ModelChoiceField方式从数据库获取】
        #models.User_tab.objects.objects.values_list('id','username')
        initial=2,
        error_messages={
            'required':''
        }
    )
    #配合从数据库调取数据实时更新展现前端页面用法
    #  def __init__(self, *args,**kwargs):
    #      super(From_check, self).__init__(*args,**kwargs)   #拷贝所有静态属性赋值给fields
    #      self.fields['area'].widget.choices=models.User_tab.objects.objects.values_list('id','username')

    # 限制类型-整型,且不能为空
    age = fields.IntegerField(
        label="年龄",
        max_value=60,
        min_value=18,
        required=True,
        error_messages={
            'required': '年龄不能为空',
            'max_value':'老爷爷不要玩儿网络啦~',
            'min_value':'未成年不能玩儿网络!!!',
            'invalid':'年龄格式有问题,必须为数字',
        }
    )
    # 限制类型-邮箱,且不能为空
    email = fields.EmailField(
        label="邮箱",
        required=True,
        error_messages={
            'required': '邮箱不能为空',
            'invalid': '邮箱格式有问题',
        }
    )

    def clean(self):  # Django预留扩展验证函数
        value_dict = self.cleaned_data  # 其他验证通过的数据
        v1 = value_dict.get('user')  # 拿到验证通过的 username 字段数据,用于再次验证
        v2 = value_dict.get('email')  # 拿到验证通过的 email 字段数据,用于再次验证
        print("验证通过的用户名是:", v1, "邮箱是", v2)
        d1 = models.User_tab.objects.filter(user=v1).count()  # 获取数据库中用户名出现次数
        d2 = models.User_tab.objects.filter(email=v2).count()  # 获取数据库中邮箱出现次数
        print("数据库获取v1是否存在", d1, "数据库获取v2是否存在", d2)
        if d1 != 0 or d2 != 0:  # 判断用户名和邮箱在数据库中是否存在
            raise ValidationError('此用户或邮箱已经被占用!')
        return self.cleaned_data
# end ---------------------------------  forms模块数据验证  ------------------------------
def Data_sub(request):
    if request.method == "GET":
        data_obj = From_check()                                        #经过验证,包含未验证通过的错误信息
        return render(request, "add_user.html", {"data_obj": data_obj})
    else:
        data_obj = From_check(request.POST,request.FILES)               #拿到from获取到的所有数据(post数据和file数据)
        if data_obj.is_valid():                                         #判断是否验证成功
            print("验证成功:",data_obj.cleaned_data)                   #已经验证成功后用户的正确数据【字典形式】
            models.User_tab.objects.create(**data_obj.cleaned_data)     #验证通过的数据写入数据库【使用**数据可避免单个字段写入】
            return redirect("/users.html")
        else:
            print("验证错误:",data_obj.errors)                         #验证失败返回的错误信息
            return render(request,"add_user.html",{"data_obj":data_obj}) #将验证数据传输到前端页面,便于取验证通过的数据和错误反馈信息
def Query_users(request):
    user_list = models.User_tab.objects.all()
    return render(request, "users.html",{'user_list':user_list,})


def Edit_user(request,nid):
    if request.method == "GET":
        data = models.User_tab.objects.filter(id=nid).first()               #数据库中查询该ID所有字段
        print("编辑字段",data)
        data_obj = From_check({'user':data.user,'pwd':data.pwd,'age':data.age,'email':data.email,})      #拿到需要编辑的对象
        return render(request,"edit_user.html",locals())                #传送前端页面可利用from组件模块生成html
    else:
        print("获取编辑后的数据:",request.POST.get,nid)
        data_obj = From_check(request.POST)
        if data_obj.is_valid():                                         #判断是否验证成功
            print("验证成功:",data_obj.cleaned_data)                   #已经验证成功后用户的正确数据【字典形式】
            models.User_tab.objects.filter(id=nid).update(**data_obj.cleaned_data)     #验证通过的数据写入数据库【使用**数据可避免单个字段写入】
            return redirect("/users.html")
        else:
            print("验证错误:",data_obj.errors)                         #验证失败返回的错误信息
            return render(request,"edit_user.html",locals()) #将验证数据传输到前端页面,便于取验证通过的数据和错误反馈信息

def Del_user(request):
    nid = request.GET .get('nid')
    print("删除ID是:",nid)
    models.User_tab.objects.filter(id=nid).delete()
    return HttpResponse("删除成功!!!")

settings.py

INSTALLED_APPS

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'APP',
]

TEMPLATES

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'APP/templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

STATIC_URL

STATIC_URL = '/static/'
urls.py
# -*- coding:utf8 -*-
from django.contrib import admin
from django.urls import path,re_path
from APP import views
urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('^add_user.html$',views.Data_sub),
    re_path('^users.html$',views.Query_users),
    re_path('^edit_user-(\d+).html$',views.Edit_user),   #获取编辑的用户id
    re_path('^del_user.html$',views.Del_user),
]
生成数据表测试

生成数据表

python manage.py makemigrations APP
python manage.py migrate

运行项目

python manage.py runserver

转载于:https://my.oschina.net/zhaojunhui/blog/2962858

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值