Django中的表单如何使用? Django如何验证前端发来的数据? ✧*。٩(ˊᗜˋ*)و✧*。 Django初体验

news/2024/7/16 6:26:06

文章目录

  • 前期准备
    • 前端准备
  • 表单基础使用
    • 创建表单
      • 表单类型
        • Field
        • CharField(Field)
        • IntergerField(Field)与 FloatField(Filed)
        • DecimalField(Field)
        • BaseTemporalField(Field)
        • RegexField(Field)
        • EmailField(Field)
        • FileField(Field)
        • ImageField(Field)
        • URLField(Field)
        • BooleanField(Field)与NullBooleanField(Field)
        • ChoiceField(Field)与TypedChoiceField(ChoiceField)
        • MultipleChoiceField(ChoiceField)与TypedMultipleChoiceField(MultipleChoiceField)
        • ComboField(Field)
        • MultiValueField(Field)
        • SplitDateTimeField(MultiValueField)
        • FilePathField(Field)
        • GenericIPAddressField(CharField)
        • SlugField(CharField)
        • UUIDField(CharField)
      • 常用验证器
      • HTML插件
      • 自定义验证
        • 多字段验证方法
    • 调用表单

前期准备

在学习表单前,如果你已经对django的数据库模型有所了解,那么表单对来说应该也比较好入手,最好对前端的表单也有一定的了解,方便写测试dome。

前端准备

这里我使用前后分类模式的开发进行。
在这里插入图片描述
当前前端,我使用vue/cli配合element制作。这里暂不放源码了。之后大家可以做个简单的输入框尝试表单接收。并且为了使用后端from验证,我将前端所以验证进行了关闭。

表单基础使用

Django中的表单丰富了传统的HTML语言中的表单。在Django中的表单,主要做以下两件事

  1. 渲染表单模板。
  2. 表单验证数据是否合法。

创建表单

我们首先在Django的APP中自己创建一个文件,名字最好是froms.py
首先我们从Django中引入froms库from django import forms
然后继承forms.Form就可以创建表单类

from django import forms


class 邮箱登陆(forms.Form):
    # 账号(邮箱)
    account = forms.EmailField()
    # 密码,设置一个最小六位,最大十八位的限制
    password = forms.CharField(min_length=6, max_length=18)

从上述实例中可以看出,表单和数据库模型是比较相似的。如果你了解数据库模型,那么表单对你来说也很容易上手。

表单类型

Field

所有表单的父类,一般不会主动调用,内置字段(方法中的属性)可用于所有表单,下列特殊标记的为后端工程师必须掌握的内置字段

内置字段以及默认值作用
required=True是否为必填项
widget=NoneHTML插件(主要作用与前端)
label=None用于生成Lable(标签)或显示内容(主要作用与前端)
initial=None初始值(主要作用与前端)
help_text=''帮助信息,在标签旁边显示(主要作用与前端)
error_messagrs=None错误信息
show_hidden_initial=False是否在当前插件后面再加一个隐藏的且具有默认值的插件(主要作用与前端,如验证两次输入是否一致)
validators=[]自定义验证规则(下方详细介绍)
localize=False是否支持本地化(根据不同语言地区访问用户显示不同语言)
disabled=False是否禁用(主要作用与前端,生成禁用的输入框)
label_suffix=Nonelabel(标签)内容后缀(主要作用与前端)

CharField(Field)

存储字符类型数据的表单

内置字段以及默认值作用
max_length=None最大长度
min_length=None最小长度
strip=True是否移除用户输入空白(这里只会移除输入开头和结尾的空白)

IntergerField(Field)与 FloatField(Filed)

IntergerField用于存入整数,FloatField用于存入浮点数

内置字段以及默认值作用
max_value=None最大值
min_value=None最小值

DecimalField(Field)

DecimalField存入小数与FloatField用于存入浮点数不同的是,DecimalField更加精确,如果涉及到金钱计算,选择DecimalField

内置字段以及默认值作用
max_value=None最大值
min_value=None最小值
max_digits=None总长度
decimal_places=None保留小数的位数

BaseTemporalField(Field)

存储字符类型数据的表单

内置字段以及默认值作用
input_formats=None时间格式化

常用的时间都继承与此类:
日期: DateField(BaseTemporalField) 格式:2020-08-01
时间: TimeField(BaseTemporalField) 格式:11:12
日期时间: DateTimeField(BaseTemporalField) 格式:2015-09-01 11:12
持续时间: DurationField(Field) 时间间隔:%d %H:%M:%S.%f

RegexField(Field)

用于存入正则表达式(自动验证是否为正则表达式)

内置字段以及默认值作用
regex自定制正则表达式
max_length=None最大长度
min_length=None最小长度

EmailField(Field)

用于存入电子邮件(自动验证电子邮件格式)
无内置字段

FileField(Field)

存储文件

内置字段以及默认值作用
allow_empty_file=False是否允许空文件

ImageField(Field)

存储图片(自动验证是否为图片)
使用此表单验证,需要下载PIL模块(pillow库,pip install Pillow)。

  • form表单中 enctype=“multipart/form-data”
  • view函数中 obj = MyForm(request.POST, request.FILES)

URLField(Field)

存储URL链接(自动验证是否为URL链接)

BooleanField(Field)与NullBooleanField(Field)

存储布尔类型数据,其中NullBooleanField为非空布尔值

ChoiceField(Field)与TypedChoiceField(ChoiceField)

单选框,其中TypedChoiceField为允许手动输入的单选框,单选框插件默认为selectwidget=select

内置字段以及默认值作用
choices=()选项,如:choices = ((0,‘索尼’),(1,‘微软’),)
coerce = lambda val: val对选中的值进行一次转换,通过lambda函数实现(只对TypedChoiceField生效)
empty_value= ''空值的默认值(只对TypedChoiceField生效)

MultipleChoiceField(ChoiceField)与TypedMultipleChoiceField(MultipleChoiceField)

多选框,其中TypedMultipleChoiceField为允许手动输入的多选框,默认插件为selectwidget=select

内置字段以及默认值作用
coerce = lambda val: val对选中的值进行一次转换,通过lambda函数实现(只对TypedMultipleChoiceField生效)
empty_value= ''空值的默认值(只对TypedMultipleChoiceField生效)

ComboField(Field)

联合表单验证,可以一次调用多种验证

内置字段以及默认值作用
fields=()使用多个验证

如: fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
验证一个最大长度在20以内的邮箱。

MultiValueField(Field)

抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用,提供接口

SplitDateTimeField(MultiValueField)

存储字符类型数据的表单

内置字段以及默认值作用
input_date_formats=None格式列表:[’%Y–%m–%d’, ‘%m%d/%Y’, ‘%m/%d/%y’]
input_time_formats=None格式列表:[’%H:%M:%S’, ‘%H:%M:%S.%f’, ‘%H:%M’]

FilePathField(Field)

文件选项,目录下文件显示在页面中

内置字段以及默认值作用
path文件夹路径
match=None正则匹配
recursive=False递归下面的文件夹
allow_files=True允许文件
allow_folders=False允许文件夹

GenericIPAddressField(CharField)

通用IP地址

内置字段以及默认值作用
protocol='both'both,ipv4,ipv6支持的IP格式
unpack_ipv4=False解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用

SlugField(CharField)

数字0-9,字母a-z,下划线_与减号(连体符)-

UUIDField(CharField)

uuid类型

常用验证器

使用表单中的validators属性,我们可以自定义一个字段的验证属性,使用自定义验证器的时候,我们需要先引入from django.core import validators

常用的验证器作用
MaxValueValidator验证最大值。
MinValueValidator验证最小值。
MinLengthValidator验证最小长度。
MaxLengthValidator验证最大长度。
EmailValidator验证是否是邮箱格式。
URLValidator验证是否是URL格式。
RegexValidator验证正则表达式。

比如我当前想要验证一个手机号,就可以通过下列方式验证

class 电话号登陆(forms.Form):
    # 账号(电话号)
    account = forms.CharField(validators=[validators.RegexValidator("1[345678]\d{9}")])

HTML插件

HTML插件作用
TextInput(Input)常规文本输入框input type="text"
NumberInput(TextInput)数字输入框
EmailInput(TextInput)邮箱输入框
URLInput(TextInput)url输入框
PasswordInput(TextInput)密码输入框
HiddenInput(TextInput)隐藏输入框
Textarea(Widget)textarea文本域
DateInput(DateTimeBaseInput)日期输入框
DateTimeInput(DateTimeBaseInput)日期时间输入框
TimeInput(DateTimeBaseInput)时间输入框
CheckboxInput多选框
Select下拉框
NullBooleanSelect非空布尔值下拉框
SelectMultiple多选下拉框
RadioSelect单选框
CheckboxSelectMultiple复选框
FileInput文件上传
ClearableFileInput
MultipleHiddenInput多隐藏输入框
SplitDateTimeWidget时间分割框(两个input框)
SplitHiddenDateTimeWidget
SelectDateWidget

自定义验证

有时候对一个字段验证,不是一个长度,一个正则表达式能够写清楚的,还需要一些其他复杂的逻辑,那么我们可以对某个字段,进行自定义的验证。比如在注册的表单验证中,我们想要验证手机号码是否已经被注册过了,那么这时候就需要在数据库(这里我使用的是Django的数据库模型调用MySQL(MySQL8.0.12)数据库。)中进行判断才知道。
碰到这种情况,我们可以自定义一个验证器,自定义验证器也很简单,使用一个函数即可自定义,def clean_自定义字段(self),其中自定义字段必须是传入的值中的一个,比如说我先在要自定义邮箱字段
在使用自定义验证中def clean_自定义字段(self)我们可以使用self.cleaned_data获取传入的值;并且使用forms.ValidationError("错误信息")传入报错信息

比如我当前想验证注册的邮箱在数据库中是否已经存在:

""".froms.py"""
from django import forms
from .models import 用户信息


class 注册账号(forms.Form):
    # 邮箱
    input_inf = forms.EmailField()

    # 验证账号时候已经存在在数据库中
    def clean_input_inf(self):
        print('表单中的信息', self.cleaned_data)
        input_inf = self.cleaned_data.get('input_inf')
        exists = 用户信息.objects.filter(电子邮箱=input_inf).exists()
        if exists:
            raise forms.ValidationError("电子邮箱已经存在")
        return input_inf
        
""".views.py"""
from django.views import View
from django.http import JsonResponse
from .froms import 注册账号

# 调用表单的方法下方会详细讲解
class 注册(View):

    def post(self, request):
        表单 = 注册账号(request.POST)
        if 表单.is_valid():
            return JsonResponse({'注册': '成功'})
        else:
            return JsonResponse({'注册': '失败'})


在这里插入图片描述

多字段验证方法

上述表单介绍中,我们介绍过联合表单验证ComboField(Field),可以一次调用多种验证,但如果我们验证的时候需要调用多个字段(如:注册时的密码与确认密码框)就可以用到多字段验证。多字段验证的方法和上述自定义验证较为相似,使用def clean(self)即可,自定义验证中使用的方法,在多字段验证同样也可以使用。
比如我当前项目需要验证注册时用户需要填写邮箱或者手机号其中的一个。

    def clean(self):
        电子邮箱 = self.cleaned_data.get('email')
        手机号 = self.cleaned_data.get('telephone')
        if 电子邮箱:
            pass
        elif 手机号:
            pass
        else:
            raise forms.ValidationError("手机号与邮箱必须选填一个")

在这里插入图片描述

调用表单

创建完成表单后,我们在调用的时候需要先引入表单,类似引入数据库模型,比如上述表单我在同一个APP的视图中引入只需使用from .froms import 邮箱登陆,如果是引入其他APP中的表单,则改变路径即可from APP.froms import 表单类
引入后,我们需要先向后端定义的表单中传入前端用户输入的表单值,比如表单 = 邮箱登陆(request.POST)这里使用的是POST方式传输。

表单常用方法作用
.cleaned_data获取表单中传入的数据
.is_valid()判断是否通过了表单验证
.errors使用ui标签返回错误信息
.errors.as_json()使用json格式返回错误信息(进行了url编码)
.errors.get_json_data()没有进行url编码的json格式
.errors.as_data()单纯返回错误信息
.errors.as_text()只返回错误文本
non_field_errors()返回与特定字段无关的错误的错误列表。(上述errors能用的方法,这里也能用)
from django.views import View
from django.http import JsonResponse
from .froms import 注册账号


class 注册(View):

    def post(self, request):
        表单 = 注册账号(request.POST)
        if 表单.is_valid():
            print(表单.cleaned_data)
            return JsonResponse({'注册信息': '成功'}, json_dumps_params={'ensure_ascii': False})
        else:
            print("0:", 表单.cleaned_data)
            print("1:", 表单.errors)
            print("2:", 表单.errors.as_json())
            print("3:", 表单.errors.get_json_data())
            print("4:", 表单.errors.as_data())
            print("5:", 表单.errors.as_text())
            print("6:", 表单.non_field_errors())
            print("7:", 表单.non_field_errors().get_json_data())
            return JsonResponse({'注册信息': '失败'}, json_dumps_params={'ensure_ascii': False})

在这里插入图片描述

如果是一个前后端不分离的项目,可能会常用到.as_table().as_ul().as_p(),分别是已table标签,ui标签,p标签返回数据。


http://www.niftyadmin.cn/n/928864.html

相关文章

String.format()的使用

参考文章: https://www.cnblogs.com/Dhouse/p/7776780.html 其中System.out.printf()的用法可参考:https://blog.csdn.net/quhongjuan12/article/details/79781101转载于:https://www.cnblogs.com/tenWood/p/10156696.html

Linux 中文乱码问题

【参考文章】:Linux系统修改编码 【参考文章】:linux 终端下命令提示乱码 【参考文章】:linux中修改字符编码 1. 查看服务器编码设置 执行 locale 命令,查看当前使用的编码格式 2. 修改服务器的编码格式 如果有需要修改服务器的编…

Django自定义的模型如何使用内置的login方法? ٩( ‘ω‘ )و Django问题

文章目录问题描述解决问题问题描述 Django中内置了一个函数from django.contrib.auth import login,可以做持久化登陆。login函数的源码中写的是login(request, user, backendNone),也就是说我们最少需要传入两个变量,一个request,一个是当前用户的数据。存入用户数据的数据库…

一个字等于多少个字节

一个字等于多少个字节,与系统硬件(总线、cpu命令字位数等)有关,不应该毫无前提地说一个字等于多少位。 正确的说法: ①:1字节(byte) 8位(bit) ②&#xff1a…

Asp.Net Core使用SignalR进行服务间调用

原文:Asp.Net Core使用SignalR进行服务间调用网上查询过很多关于ASP.NET core使用SignalR的简单例子,但是大部分都是简易聊天功能,今天心血来潮就搞了个使用SignalR进行服务间调用的简单DEMO。 至于SignalR是什么我就不多说了,微软官方文档也…

前后端分离的情况下,vue保存cookie时碰到的坑! (axios.defaults.withCredentials = true;) 前方巨坑,请小心!!!

文章目录一号坑问题描述解决方案二号坑问题描述解决方法总结一号坑 问题描述 当我们的项目是前后端分离的模式时,vue不会自动帮我们保存后端传来的cookie! 解决方案 我们需要在main中添加axios.defaults.withCredentials true 二号坑 问题描述 如果你之前处理过跨域方面…

Python列表的相关操作与方法

Python列表的相关操作与方法 1.列表 why:int、bool、str存在缺陷 str:存储少量的数据;所有的操作获取的内容都是 str类型,存储的数据类型单一。what: 列表可以承载任意数据类型,存储大量的数据。Python常用的容器型数据…

bzoj 2119 股市的预测

后缀数组好题。 差分不用说了。统计形如ABA的数量。 按照什么顺序统计答案呢? 枚举B的左端点?但是位置连续,并不代表sa的位置连续,所以难以往两边统计A部分的贡献。 我们转而枚举A的长度和起始位置,直接这样做是O(n^2)…