forms组件补充与ModelForm简单使用与cookie与session
forms组件钩子函数
钩子函数可以让字段在原有的校验功能上在新增一个自定义校验的功能。
局部钩子
校验单个字段,在form类中编写一个函数:
def clean_字段名(self):
    校验代码
    return 字段值
比如:判断用户名name字段值是否存在:
class LoginForm(forms.Form):
    name = forms.CharField(max_length=8)
    def clean_name(self):
        # 先获取字段值
        name = self.clean_data.get('name')
        # 判断是否存在
        is_exist = models.User.objects.filter(name=name)
        if is_exist:
            # 错误信息展示
            self.add_error('name', '用户名已存在')
        # 最后将你勾上来的name返回回去
        return name
全局钩子
校验多个字段,在form类中编写一个函数:
def clean(self):
    校验代码
    return self.cleaned_data
比如校验两个字段值是否一致:
class LoginForm(forms.Form):
    name = forms.CharField(max_length=8)
    confirm_name = forms.CharField(max_length=8)
    def clean(self):
        # 先获取字段值
        name = self.clean_data.get('name')
        confirm_name = self.clean_data.get('confirm_name')
        # 判断是否一致
        if name != confirm_name:
            # 错误信息展示
            self.add_error('confirm_name', '两次用户名不一致')
        # 最后将整个数据返回
        return self.clean_data

forms组件字段参数
字段参数
| 参数 | 作用 | 
|---|---|
| min_length | 最小长度 | 
| max_length | 最大长度 | 
| label | 字段名称 | 
| error_messages | 错误信息展示 | 
| min_value | 最小值 | 
| max_value | 最大值 | 
| initial | 默认值 | 
| validators | 正则校验器 | 
| widget | 控制渲染出来的标签各项属性 | 
| choices | 选择类型的标签内部对应关系 | 
validators详解
演示:
from django.core.validators import RegexValidator
class MyForm(forms.Form):
    phone = forms.CharField(
        validators=[
            RegexValidator(r'^[0-9]+$', '请输入数字'),
            RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
        ]
    )
choices详解
定义选择类型的标签内部对应关系,可以直接编写,也可以从数据库中获取。
方式一:
# 直接编写
class MyForm(forms.Form):
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
    )
# 数据库获取数据
class MyForm(forms.Form):
    course = forms.fields.ChoiceField(
        choices=models.Course.objects.all().values_list('id', 'name'),
        label="课程",
    )
方式二:
# 直接编写
class MyForm(forms.Form):
    gender = forms.fields.ChoiceField(label="性别")
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['gender'].choices = ((1, "男"), (2, "女"), (3, "保密"))
# 数据库获取数据
class MyForm(forms.Form):
    course = forms.fields.ChoiceField(label="课程")
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['course'].choices = models.Course.objects.all().values_list('id', 'name')
widget详解
使用form组件生成的标签无法在前端自定义样式,只能使用widget来控制。
基本语法:
widgets=forms.widgets.控制type的类型(
    attrs={'属性1':'值',...}
)
比如:
class MyForm(forms.Form):
    name = forms.CharField(
        widget=forms.widgets.TextInput(
            attr={'class':'c1'}
        )
    )
文本输入框
widget=forms.widgets.TextInput()
密码输入框
widget=forms.widgets.PasswordInput()
数字输入框
widget=forms.widgets.NumberInput()
radio
class MyForm(forms.Form):
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        widget=forms.widgets.RadioSelect()
    )
单选select
class MyForm(forms.Form):
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        widget=forms.widgets.Select()
    )
多选select
class MyForm(forms.Form):
    hobby = forms.fields.MultipleChoiceField(
        choices=((1, "read"), (2, "run"), (3, "game")),
        label="爱好",
        widget=forms.widgets.SelectMultiple()
    )
单选checkbox
class MyForm(forms.Form):
    keep = forms.ChoiceField(
        label="是否记住密码",
        widget=forms.widgets.CheckboxInput()
    )
多选checkbox
class MyForm(forms.Form):
    hobby = forms.fields.MultipleChoiceField(
        choices=((1, "read"), (2, "run"), (3, "game")),
        label="爱好",
        widget=forms.widgets.CheckboxSelectMultiple()
    )

forms组件字段类型
常见字段
| 字段 | 作用 | 
|---|---|
| CharField() | 文本字段 | 
| IntegerField() | 数字字段 | 
| DecimalField() | Decimal字段 | 
| EmailField() | 邮箱校验字段 | 
| ChoiceField() | 单选字段 | 
| MultipleChoiceField() | 多选字段 | 
其他字段
点击查看
Field
    required=True,               是否允许为空
    widget=None,                 HTML插件
    label=None,                  用于生成Label标签或显示内容
    initial=None,                初始值
    help_text='',                帮助信息(在标签旁边显示)
    error_messages=None,         错误信息 {'required': '不能为空', 'invalid': '格式错误'}
    validators=[],               自定义验证规则
    localize=False,              是否支持本地化
    disabled=False,              是否可以编辑
    label_suffix=None            Label内容后缀
CharField(Field)
    max_length=None,             最大长度
    min_length=None,             最小长度
    strip=True                   是否移除用户输入空白
IntegerField(Field)
    max_value=None,              最大值
    min_value=None,              最小值
FloatField(IntegerField)
    ...
DecimalField(IntegerField)
    max_value=None,              最大值
    min_value=None,              最小值
    max_digits=None,             总长度
    decimal_places=None,         小数位长度
BaseTemporalField(Field)
    input_formats=None          时间格式化   
DateField(BaseTemporalField)    格式:2015-09-01
TimeField(BaseTemporalField)    格式:11:12
DateTimeField(BaseTemporalField)格式:2015-09-01 11:12
DurationField(Field)            时间间隔:%d %H:%M:%S.%f
    ...
RegexField(CharField)
    regex,                      自定制正则表达式
    max_length=None,            最大长度
    min_length=None,            最小长度
    error_message=None,         忽略,错误信息使用 error_messages={'invalid': '...'}
EmailField(CharField)
    ...
FileField(Field)
    allow_empty_file=False     是否允许空文件
ImageField(FileField)
    ...
    注:需要PIL模块,pip3 install Pillow
    以上两个字典使用时,需要注意两点:
        - form表单中 enctype="multipart/form-data"
        - view函数中 obj = MyForm(request.POST, request.FILES)
URLField(Field)
    ...
BooleanField(Field)
    ...
NullBooleanField(BooleanField)
    ...
ChoiceField(Field)
    ...
    choices=(),                选项,如:choices = ((0,'上海'),(1,'北京'),)
    required=True,             是否必填
    widget=None,               插件,默认select插件
    label=None,                Label内容
    initial=None,              初始值
    help_text='',              帮助提示
ModelChoiceField(ChoiceField)
    ...                        django.forms.models.ModelChoiceField
    queryset,                  # 查询数据库中的数据
    empty_label="---------",   # 默认空显示内容
    to_field_name=None,        # HTML中value的值对应的字段
    limit_choices_to=None      # ModelForm中对queryset二次筛选
ModelMultipleChoiceField(ModelChoiceField)
    ...                        django.forms.models.ModelMultipleChoiceField
TypedChoiceField(ChoiceField)
    coerce = lambda val: val   对选中的值进行一次转换
    empty_value= ''            空值的默认值
MultipleChoiceField(ChoiceField)
    ...
TypedMultipleChoiceField(MultipleChoiceField)
    coerce = lambda val: val   对选中的每一个值进行一次转换
    empty_value= ''            空值的默认值
ComboField(Field)
    fields=()                  使用多个验证,如下:即验证最大长度20,又验证邮箱格式
                               fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
MultiValueField(Field)
    PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合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(ChoiceField)     文件选项,目录下文件显示在页面中
    path,                      文件夹路径
    match=None,                正则匹配
    recursive=False,           递归下面的文件夹
    allow_files=True,          允许文件
    allow_folders=False,       允许文件夹
    required=True,
    widget=None,
    label=None,
    initial=None,
    help_text=''
GenericIPAddressField
    protocol='both',           both,ipv4,ipv6支持的IP格式
    unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用
SlugField(CharField)           数字,字母,下划线,减号(连字符)
    ...
UUIDField(CharField)           uuid类型
ModelForm简单使用
forms组件主要配合models里面的模型类一起使用,但是模型类里面的字段需要在forms类中相当于重写一遍,代码冗余,为了更好的结合forms与models的关系,有了一个ModelForm(基于forms组件)。
简单使用
models:
class User(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    addr = models.CharField(max_length=32)
forms:
class MyUser(forms.ModelForm):
    class Meta:
        model = models.User  # 指定关联的表
        fields = '__all__'  # 所有的字段全部生成对应的forms字段
        labels = {  # 每个字段标签的labels参数
            'name': '用户名',
            'age': '年龄',
            'addr': '地址'
        }
        widgets = {  # 每个字段标签的widget参数
            "name": forms.widgets.TextInput(attrs={"class": "form-control"}),
        }
views:
添加数据
def home(request):
    form_obj = MyUser()
    if request.method == 'POST':
        if form_obj.is_valid():
            # 获取提交的数据
            form_obj = MyUser(request.POST)
            # 保存数据,向表中添加数据
            form_obj.save()
    return render(request, 'home.html', locals())
编辑数据
def home(request):
    form_obj = MyUser()
    if request.method == 'POST':
        if form_obj.is_valid():
            # 获取数据看看是否已存在
            edit_obj = models.User.objects.filter(name=request.POST.get('name')).first()
            # 新增还是保存就取决于instance参数有没有值
            form_obj = MyUser(request.POST,instance=edit_obj)
            # 保存数据
            form_obj.save()
    return render(request, 'home.html', locals())
cookie与session简介
cookie
简介
HTTP协议中有一个特性:无状态,意思是服务端不会保存客户端的数据,客户端一直向服务端发送请求,服务端都不会认识客户端,而cookie就可以让服务端认识客户端。
cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。
比如在一些网站中,你登陆后就不需要在登录了,这就是因为你的信息被保存在了cookie中,登录一次后,那些网站就知道你已经登录了。
原理
由服务器产生内容,浏览器收到后保存在cookie;当浏览器再次访问时,浏览器会自动带上cookie,这样服务器就能通过cookie的内容来判断这个是“谁”了。

session
简介
如果数据保存在cookie中,很容易被看到,安全性太低,因此需要一个新东西,那就是session。它把数据保存在了服务端,并给客户端返回一个随机字符串保存,这个随机字符串与服务端里的数据对应。每次客户端发送请求时会携带该随机字符串,服务端会进行比对。
django操作cookie
基本使用
设置cookie
def index(request):
    res = HttpResponse('index页面')
    res.set_cookie('name', 'abcd')
    return res
获取cookie
def home(request):
    if request.COOKIE.get('name'):
        return HttpResponse('cookie有name')
    return HttpResponse('cookie中没有name')

进阶
在上述例子中,如果我想要给多个视图函数添加一个判断cookie的功能,我们可以使用装饰器:
def login_auth(func):
    def inner(request, *args, **kwargs):
        if request.COOKIES.get('name'):
            return func(request, *args, **kwargs)
        return HttpResponse('你的cookie中还没有name')
    return inner
												
											forms组件补充与ModelForm简单使用与cookie与session的更多相关文章
- ModelForm组件和forms组件补充
		
forms组件补充: forms组件的三个字段:ChoiceField, ModelChoiceField & ModelMultipleChoiceField # forms组件:Choic ...
 - Django基础之forms组件中的ModelForm组件
		
Django的model form组件 这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看一下这个东西怎么用:比如我们的数据库中有这样 ...
 - 简单总结下 cookie、session
		
Cookies: 定义:cookie 中文意思是"小甜饼",但是,在互联网中它跟食品没有半毛钱关系,它主要是由web服务器应用程序创建,在客户端计算机中保存,问题来了, ...
 - Python-S9—Day85-ORM项目实战之forms组件以及Modelform补充、跨域请求及应用
		
01 forms组件补充1 02 forms组件补充2 03 ModelForm回顾 04 浏览器的历史 05 jsonop实现跨域请求 06 jsonop实现跨域请求2 07 jsonop实现跨域请 ...
 - forms 组件的功能和使用
		
forms组件 先自己实现注册功能,并且对用户输入的信息加限制条件 如果用户输入的信息不符合条件,前端展示报错信息 注册示例: 1.前端渲染标签获取用户输入 >>> 前端渲染标签 2 ...
 - {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm
		
Django基础十之Form和ModelForm组件 本节目录 一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 Model ...
 - Django序列化组件与数据批量操作与简单使用Forms组件
		
目录 SweetAlert前端插件 Django自带的序列化组件 批量数据操作 分页器与推导流程 Forms组件之创建 Forms组件之数据校验 Forms组件之渲染标签 Forms组件之信息展示 S ...
 - Django框架的forms组件与一些补充
		
目录 一.多对多的三种创建方式 1. 全自动 2. 纯手撸(了解) 3. 半自动(强烈推荐) 二.forms组件 1. 如何使用forms组件 2. 使用forms组件校验数据 3. 使用forms组 ...
 - python 全栈开发,Day78(Django组件-forms组件)
		
一.Django组件-forms组件 forms组件 django中的Form组件有以下几个功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显 ...
 
随机推荐
- H5优化:canonical标签该如何正确使用
			
对一组内容完全相同或高度相似的网页,通过使用Canonical标签可以告诉搜索引擎哪个页面为规范的网页,能够规范网址并避免搜索结果中出现多个内容相同或相似的页面,帮助解决重复内容的收录问题,避免网站相 ...
 - 从ES6重新认识JavaScript设计模式(三): 建造者模式
			
1 什么是建造者模式? 建造者模式(Builder)是将一个复杂对象的构建层与其表示层相互分离,同样的构建过程可采用不同的表示. 建造者模式的特点是分步构建一个复杂的对象,可以用不同组合或顺序建造出不 ...
 - C#编写一个控制台应用程序,可根据输入的月份判断所在季节
			
编写一个控制台应用程序,可根据输入的月份判断所在季节 代码: using System; using System.Collections.Generic; using System.Linq; us ...
 - 【小程序开发】文本text-overflow属性的使用
			
text-overflow原本是CSS3的一个属性,在微信小程序中也支持. text-overflow文本溢出显示省略号~ 注:使用text-overflow时,需要设置固定的宽度才起作用,所以该元素 ...
 - 防止自己的页面不被其他网站的页面的iframe引用
			
方法用二: 一.设置http请求头的X-Frame-Options: X-Frame-Options可以设置三个值 1.DENY 代表页面不会能被嵌入到iframe或者frame里 2.SAMEOR ...
 - MySQL性能优化的5个维度
			
面试官如果问你:你会从哪些维度进行MySQL性能优化?你会怎么回答? 所谓的性能优化,一般针对的是MySQL查询的优化.既然是优化查询,我们自然要先知道查询操作要经过哪些环节,然后思考可以在哪些环节进 ...
 - Java基础之浅谈泛型
			
简单的介绍了Java泛型类型的使用.上手容易,深入很难.
 - python循环与基本数据类型内置方法
			
今天又是充满希望的一天呢 一.python循环 1.wuile与else连用 当while没有被关键'break'主动结束的情况下 正常结束循环体代码之后会执行else的子代码 "" ...
 - CPU乱序执行问题
			
CPU为了提高执行效率,会在一条指令执行的过程中(比如去内存读数据,读数据的过程相较于CPU的执行速度慢100倍以上,cpu处于等待状态),这个时候cpu会分析接下来的指令是否正在执行的指令相关联,如 ...
 - Ubu18下cpptest安装
			
1.环境安装 sudo apt install g++ sudo apt install automake sudo apt install autoconf sudo apt install lib ...