Django 进阶篇二

Posted 终点即起点

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django 进阶篇二相关的知识,希望对你有一定的参考价值。

Django Forms表单

在实际的生产环境中比如登录和验证的时候,我们一般都使用Jquery+ajax来判断用户的输入是否为空,假如JS被禁用的话,咱们这个认证屏障是不是就消失了呢?(虽然一般不会禁用掉但是还是存在风险)

所以我们一般做两种认证一种是前端做一遍认证,在后端做一遍认证

案例:

#/usr/bin/env python
#-*- coding:utf-8 -*-
from django.shortcuts import render

# Create your views here.

def user_list(request):
    host = request.POST.get(host)
    port = request.POST.get(port)
    mail = request.POST.get(mail)
    mobile = request.POST.get(mobile)
    # 这里有个问题,如果,这个from表单有20个input,你在这里是不是的取20次?

    # 验证:
    # 输入不能为空,并且有的可以为空有的不可以为空
    # 如果email = 11123123  这样合法吗?
    # 如果mobile = 11123123  这样合法吗?
    # 如果ip = 11123123  这样合法吗?
    ‘‘‘
    你在这里是不是需要做一大堆的输入验证啊?并且有很多这种页面会存在这种情况,如果每个函数都这样做估计就累死了
    ‘‘‘
    return render(request,user_list.html)

怎样能解决这个问题呢?通过Django的form来实现,其他语言也有叫做(模型绑定)

Django的form的作用:

1、生成html标签

2、用来做用户提交的验证

一、生成html标签

views

# -*- coding:utf-8 -*-
from django.shortcuts import render, redirect
from usermanager import models
from django import forms

# Create your views here.

class UserInfo(forms.Form):
    user = forms.CharField(required=True)    # required是否可以为空,如果为False说明可以为空,默认为True
    pwd = forms.CharField()     # 如果required不写默认为Ture
    port = forms.CharField()
    host = forms.GenericIPAddressField()   # 通用IP地址格式
    email = forms.EmailField(required=False)


def user_list(request):
    obj = UserInfo()   # 创建了这个对象
    return render(request,
                  user_list.html,
                  {obj: obj})  # 然后把对象传给html

html调用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form action="/user_list/" method="post">
        <p>用户:{{ obj.user }}</p>
        <p>密码:{{ obj.pwd }}</p>
        <p>端口:{{ obj.port }}</p>
        <p>主机:{{ obj.host }}</p>
        <p>邮箱:{{ obj.email }}</p>
        <input type="submit" value="submit"  />
    </form>
</body>
</html>

把我们的对象穿进去,html在引用的时候直接obj.host就可以自动生成html标签,然后看下html显示:

技术分享

二、简单的form表单验证用户输入的内容

def user_list(request):
    obj = UserInfo() # 创建了这个对象
    if request.method == POST:
        # 获取用户输入一句话就搞定
        user_input_obj = UserInfo(request.POST)
        ‘‘‘
        咱们把post过来的数据当参数传给UserInfo咱们定义的这个类,UserInfo会自动会去你提交的数据
        email/host/port/mobile 自动的封装到user_input_obj里,封装到这个对象里我们就可以判断输入是否合法
        ‘‘‘
        print user_input_obj.is_valid() #

    return render(request,user_list.html,{obj:obj})    # 然后把对象传给html

 

当我们输入不合法的时候,(在创建类设置的需求)为空、或者不是email格式的时候!

技术分享

这样在后端我们是不是就有一套验证的机制?就可以通过is_valid()来判断用户输入是否合法!如果不合法就把返回信息发送过去,如果合法获取数据操作即可!

捕获错误信息并返回

from django import forms

class UserInfo(forms.Form):
     email = forms.EmailField(required=True) #required是否可以为空,如果为False说明可以为空
     host = forms.CharField() #如果required不写默认为Ture
     port = forms.CharField()
     mobile = forms.CharField()

def user_list(request):
    obj = UserInfo() #创建了这个对象
    if request.method == POST:
        #获取用户输入一句话就搞定
        user_input_obj = UserInfo(request.POST)
        ‘‘‘
        咱们把post过来的数据当参数传给UserInfo咱们定义的这个类,UserInfo会自动会去你提交的数据
        email/host/port/mobile 自动的封装到user_input_obj里,封装到这个对象里我们就可以判断输入是否合法
        ‘‘‘
        if user_input_obj.is_valid(): #判断用户输入是否合法
            data = user_input_obj.clean() #获取用户输入
            print data
        else:
            #如果发生错误,捕捉错误
            error_msg = user_input_obj.errors
            print error_msg #打印一下然后看下他的类型
            ‘‘‘
            <ul class="errorlist">
            <li>mobile<ul class="errorlist"><li>This field is required.
            </li></ul></li>
            <li>host<ul class="errorlist"><li>This field is required.</li></ul></li>
            <li>port<ul class="errorlist"><li>This field is required.</li></ul></li>
            </ul>
            ‘‘‘
            #然后把错误信息返回
            return render(request,user_list.html,{obj:obj,errors:error_msg,})#然后把对象传给html,在把错误信息传递过去
    return render(request,user_list.html,{obj:obj,})#然后把对象传给html

html标签,使用error输出

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form action="/user_list/" method="post">
        <p>用户:{{ obj.user }}<span>{{ errors.user }}</span></p>
        <p>密码:{{ obj.pwd }}<span>{{ errors.pwd }}</span></p>
        <p>端口:{{ obj.port }}<span>{{ errors.port }}</span></p>
        <p>主机:{{ obj.host }}<span>{{ errors.host }}</span></p>
        <p>邮箱:{{ obj.email }}<span>{{ errors.email }}</span></p>
        <input type="submit" value="submit"  />
    </form>
</body>
</html>

3、form表单定制化

3.1、自定义报错内容

  在form里有一个参数:error_messages  在他这里就可以定义报错内容

class UserInfo(forms.Form):
     email = forms.EmailField(required=True,error_messages={required:u邮箱不能为空}) # required是否可以为空,如果为False说明可以为空
     host = forms.CharField(error_messages={required:u主机不能为空}) # 如果required不写默认为Ture
     port = forms.CharField(error_messages={required:u端口不能为空})
     mobile = forms.CharField(error_messages={required:u手机不能为空})

 3.2、我想给form表单添加一个属性

class UserInfo(forms.Form):
     email = forms.EmailField(required=True,error_messages={required:u邮箱不能为空}) # required是否可以为空,如果为False说明可以为空
     host = forms.CharField(error_messages={required:u主机不能为空}) #  如果required不写默认为Ture
     port = forms.CharField(error_messages={required:u端口不能为空})
     mobile = forms.CharField(error_messages={required:u手机不能为空},
                              widget=forms.TextInput(attrs={class:form-control,placeholder:u手机号码})
                                    # 这里默认是TextInput,标签
                              )

 3.3、在给他增加一个备注

class UserInfo(forms.Form):
     email = forms.EmailField(required=True,error_messages={required:u邮箱不能为空}) #required是否可以为空,如果为False说明可以为空
     host = forms.CharField(error_messages={required:u主机不能为空}) #如果required不写默认为Ture
     port = forms.CharField(error_messages={required:u端口不能为空})
     mobile = forms.CharField(error_messages={required:u手机不能为空},
                              widget=forms.TextInput(attrs={class:form-control,placeholder:u手机号码})
                                    #这里默认是TextInput,标签
                              )
     # 新增一个备注(textarea)
     memo = forms.CharField(required=False,
                            widget=forms.Textarea(attrs={class:form-control,placeholder:u备注})

     )

html代码

    <form action="/user_list/" method="post">
        <p>主机:{{ obj.host }}<span>{{ errors.host }}</span></p>
        <p>端口:{{ obj.port }}<span>{{ errors.port }}</span></p>
        <p>邮箱:{{ obj.email }}<span>{{ errors.email }}</span></p>
        <p>手机:{{ obj.mobile }}<span>{{ errors.mobile }}</span></p>
        <p>备注:{{ obj.memo }}<span>{{ errors.memo }}</span></p>

        <input type="submit" value="submit"/>
    </form>

4、自定义正则表达式增加判断规则

import re
from django import forms
from django.core.exceptions import ValidationError


#自定义方法
def mobile_validate(value):
    mobile_re = re.compile(r^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$) #正则匹配
    if not mobile_re.match(value):
        raise ValidationError(手机号码格式错误) #如果没有匹配到主动触发一个错误


class UserInfo(forms.Form):
     email = forms.EmailField(required=True,error_messages={required:u邮箱不能为空}) #required是否可以为空,如果为False说明可以为空
     host = forms.CharField(error_messages={required:u主机不能为空}) #如果required不写默认为Ture
     port = forms.CharField(error_messages={required:u端口不能为空})

     # 默认mobile里有一个默认为空的机制,我们在原有的参数里增加怎们自定义的方法
     mobile = forms.CharField(validators=[mobile_validate,],# 应用咱们自己定义的规则
                              error_messages={required:u手机不能为空},
                              widget=forms.TextInput(attrs={class:form-control,placeholder:u手机号码})
                                    # 这里默认是TextInput,标签
                              )
     # 新增一个备注(textarea)
     memo = forms.CharField(required=False,
                            widget=forms.Textarea(attrs={class:form-control,placeholder:u备注})

     )

如果为空的话会提示,不能为空如果格式不对的话会提示手机号码格式错误

5、生成select标签

class UserInfo(forms.Form):

    user_type_choice = (
        (0, u普通用户),
        (1, u高级用户),)

    user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,attrs={class:form-control}))

 html内

<form action="/user_list/" method="post">
        <p>用户类型:{{ obj.user_type }}<span>{{ errors.user_type }}</span></p>
        <p>主机:{{ obj.host }}<span>{{ errors.host }}</span></p>
        <p>端口:{{ obj.port }}<span>{{ errors.port }}</span></p>
        <p>邮箱:{{ obj.email }}<span>{{ errors.email }}</span></p>
        <p>手机:{{ obj.mobile }}<span>{{ errors.mobile }}</span></p>
        <p>备注:{{ obj.memo }}<span>{{ errors.memo }}</span></p>

        <input type="submit" value="submit"/>
    </form>

技术分享

6、关于后端验证

 这个后端验证是必须要有验证机制的,前端可以不写但是后端必须要写!前端的JS是可以被禁用掉到。

6、Django form漂亮的显示错误信息

设置显示error的样式

error_msg = user_input_obj.errors.as_data()#这里原来什么都没写,默认是ul的样式,默认是as_ul(),如果我们写成as_data()返回的就是一个原生的字符串
            #还有一个as_json

 实例:

import re
from django import forms
from django.core.exceptions import ValidationError

# 自定义方法
def mobile_validate(value):
    mobile_re = re.compile(r^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$) # 正则匹配
    if not mobile_re.match(value):
        raise ValidationError(手机号码格式错误) # 如果没有匹配到主动出发一个错误


class UserInfo(forms.Form):

    user_type_choice = (
        (0, u普通用户),
        (1, u高级用户),)

    user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,attrs={class:form-control}))

    email = forms.EmailField(required=True,error_messages={required:u邮箱不能为空}) # required是否可以为空,如果为False说明可以为空
    host = forms.CharField(error_messages={required:u主机不能为空}) # 如果required不写默认为Ture
    port = forms.CharField(error_messages={required:u端口不能为空})

    # 默认mobile里有一个默认为空的机制,我们在原有的参数里增加怎们自定义的方法
    mobile = forms.CharField(validators=[mobile_validate,],# 应用咱们自己定义的规则
                              error_messages={required:u手机不能为空},
                              widget=forms.TextInput(attrs={class:form-control,placeholder:u手机号码})
                                    # 这里默认是TextInput,标签
                              )
    # 新增一个备注
    memo = forms.CharField(required=False,
                            widget=forms.Textarea(attrs={class:form-control,placeholder:u备注}))

def user_list(request):
    obj = UserInfo() #创建了这个对象
    if request.method == POST:
        #获取用户输入一句话就搞定
        user_input_obj = UserInfo(request.POST)

        if user_input_obj.is_valid(): #判断用户输入是否合法
            data = user_input_obj.clean() #获取用户输入
            print data
        else:
            #如果发生错误,捕捉错误
            error_msg = user_input_obj.errors.as_data()#这里原来什么都没写,默认是ul的样式,默认是as_ul(),如果我们写成as_data()返回的就是一个原生的字符串
            #还有一个as_json

            print error_msg #打印一下然后看下他的类型
            #然后把错误信息返回
            return render(request,user_list.html,{obj:obj,errors:error_msg,})#然后把对象传给html,在把错误信息传递过去
    return render(request,user_list.html,{obj:obj,})#然后把对象传给html

看下他的实际是什么内容: 

{mobile: [ValidationError([u\u624b\u673a\u4e0d\u80fd\u4e3a\u7a7a])], 
host: [ValidationError([u\u4e3b\u673a\u4e0d\u80fd\u4e3a\u7a7a])], 
email: [ValidationError([u\u90ae\u7bb1\u4e0d\u80fd\u4e3a\u7a7a])], 
port: [ValidationError([u\u7aef\u53e3\u4e0d\u80fd\u4e3a\u7a7a])]}

所以我们自定义一个模板语言对其进行修饰:

技术分享

然后在html中调用

{% load cmdb_tag %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Shuai</title>
</head>
<body>
    <form action="/user_list/" method="post">
        <p>用户类型:{{ obj.user_type }}<span>{% error_message errors.user_type %}</span></p>
        <p>主机:{{ obj.host }}<span>{% error_message errors.host %}</span></p>
        <p>端口:{{ obj.port }}<span>{% error_message errors.port %}</span></p>
        <p>邮箱:{{ obj.email }}<span>{% error_message errors.email %}</span></p>
        <p>手机:{{ obj.mobile }}<span>{% error_message errors.mobile %}</span></p>
        <p>备注:{{ obj.memo }}<span>{% error_message errors.memo %}</span></p>
        <input type="submit" value="submit"/>
    </form>
</body>
</html>

显示效果如下:

技术分享

因为模板语言不支持用索引的方式取值,所以我们通过自定义simp_tag来进行取值

 

 

 

持续更新

 

以上是关于Django 进阶篇二的主要内容,如果未能解决你的问题,请参考以下文章

Web应用的组件化进阶篇

Django进阶篇

Web框架django进阶篇

Python之路,Day15 - Django适当进阶篇

Django 进阶篇

Django进阶篇