django_forms

一.forms组件的钩子函数

# 1.钩子函数的含义其实就是在程序的执行过程中穿插额外的逻辑
	
# 2.校验用户名是否已存在
	钩子函数之局部钩子(校验单个字段)
'局部钩子:校验用户名是否已存在(一次性只能勾一个人)'
'钩子函数是数据经过了字段第一层参数校验之后才会执行'
def clean_name(self):  # 自动生成的函数名 专门用于对name字段添加额外的校验规则
        # 1.先获取用户名
        name = self.cleaned_data.get('name')
        # 2.判断用户名是否已存在
        is_exist = models.User.objects.filter(name=name)  # 从数据库中获取name字段对比
        if is_exist:
            # 3.提示信息
            self.add_error('name', '用户名已存在')
        # 4.最后将你勾上来的name返回回去
        return name

    
# 3.校验密码和确认密码是否一致
钩子函数之全局钩子(校验多个字段)
# 全局钩子:校验密码与确认密码是否一致(一次性可以勾多个人)
def clean(self):
        # 1.获取多个字段数据
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if not password == confirm_password:
            self.add_error('confirm_password', '两次密码不一致')
        # 最后将整个数据返回
        return self.cleaned_data

二.forms组件字段参数

min_length				# 最小长度
max_length				# 最大长度
label					# 字段名称
error_messages	                        # 错误提示
min_value				# 最小值
max_value				# 最大值
initial					# 默认值
validators				# 正则校验器

from django.core.validators import RegexValidator
phone = forms.CharField(
validators=[
         RegexValidator(r'^[0-9]+$', '请输入数字'),
         RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],)


widget					# 控制渲染出来的标签各项属性

password = forms.CharField( widget=forms.widgets.PasswordInput(attrs={'class':'form-control'}))      # 样式

password1 = forms.CharField(  
widget=forms.widgets.控制type的类型(attrs=控制各项属性:class id ...))     # 样式
    			 # PasswordInput密文展示默认Text
    
choices					# 选择类型的标签内部对应关系
	可以直接编写 也可以从数据库中获取

# 自己编写
  	hobby = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
    )

# 数据库查找
    def __init__(self, *args, **kwargs):
        super(MyForm,self).__init__(*args, **kwargs)
        self.fields['hobby'].choices = models.Classes.objects.all().values_list('id','caption')

三.字段类型

1.1单选Select

hobby = forms.ChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=3,
        widget=forms.widgets.Select())

1.2多选 SelectMultiple

  hobby = forms.MultipleChoiceField(    
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple())

1.3单选CheckboxInput

keep = forms.ChoiceField(
        label="是否记还钱",
        initial="checked",
        widget=forms.widgets.CheckboxInput())

1.4多选CheckboxSelectMultiple

    hobby1 = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple())

四.forms组件源码分析

def is_valid(self):
    return self.is_bound and not self.errors
# 查看类源码发现只要给类传参self.is_bound肯定是True

@property
def errors(self):
   	if self._errors is None:
       self.full_clean()
    return self._errors
# 查看了源码发现self._errors初始化就是None 所以肯定走full_clean方法

# 查看源码发现校验数据的整个过程内部都有异常处理机制
from django.core.exceptions import ValidationErrorx
raise ValidationError('用户名不存在 你个DSB')

五.ModelForm简介

1.forms配合models类 一并使用的
2.models类字段名有几个 froms类中就要重复写一遍
3.结合froms与models关系 有了ModelForm(基于forms组件)
class MyUser(forms.ModelForm):
    class Meta:
        model = models.User
        fields = '__all__'
        exclude = ('addr',)   # 清除指定字段
        labels = {
            'name':'姓名',
            'age':'年龄',
            'addr':'地址',
            'email':'邮箱'
        }
def home(request):
    from_obj = MyUser()
    if request.method == 'POST':
        from_obj = MyUser(request.POST)
        if from_obj.is_valid():   
            # from_obj.save()    # 保存数据
            user_obj = models.User.objects.filter(pk=2).first()
            from_obj = MyUser(request.POST,instance=user_obj)
            # instance          # 参数有就编辑 没有就保存
            from_obj.save()     # 基于表编辑数据从新保存
            
    return render(request,'home.html',locals())

六.cookie与session简介

# 1.cookie简介
	早期的互联网应用程序都是不保存用户状态的,所有人发送请求返回的都是相同的页面
  现如今几乎所有的应用程序都可以保存用户状态!!!>>>:如何实现的???
  	HTTP协议四大特性之一:无状态
  让服务端知道你是谁的方式很单一>>>:携带用户名和密码(身份标识)
    每次操作之前都需要输入用户名和密码
  当你成功登录之后浏览器会在本地帮你保存用户名和密码
  	每次操作浏览器自动发送用户名和密码
# cookie本质
  	指代服务端让客户端保存的数据(存储在客户端上与用户信息相关的数据)
    '''简单的记忆:cookie就是存在客户端的东西'''
    
# session简介
	早期的cookie是直接存储的用户明文相关信息 不安全
 	用户登录成功之后 服务端生成一个随机字符串 返回给客户端保存
  之后客户端每次发请求携带该随机字符串 服务端获取之后比对后台数据
  	'eg:'
      服务端
      	随机字符串1       用户数据1
        随机字符串2	 用户数据2
        随机字符串3	 用户数据3
      客户端
      	随机字符串1、随机字符串2、随机字符串3
# session本质
  	指代服务端保存的跟用户信息相关的数据
    '''简单的记忆:session就是存在服务端的东西'''
"""
1.session的工作必须依赖于cookie
2.客户端也有权拒绝保存数据
"""
ps:针对身份标识问题有很多方式  cookie和session是最基本的
  	token、jwt...

七.django操作cookie

# 不直接返回对象 而是先用变量名指代 然后操作对象方法
def login(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        if name == 'thn':
            res = HttpResponse('登陆成功')
            res.set_cookie('name','thn')
            return res
    return render(request, 'login.html')
# 基本使用
	res.set_cookie()  # 设置
    res.COOKIE.get()  # 获取
# 有很多视图函数需要添加登录认证 有时候又需要取消登录认证
def login_ai(func_name):
    def inner(request,*args,**kwargs):
        if request.COOKIES.get('name'):
            res = func_name(request,*args,**kwargs)
            return res
        else:
            return redirect('/login/')
    return inner


def login(request):
    if request.method == 'POST':
        name = request.POST.get('name')
        if name == 'thn':
            res = redirect('/home/')
            res.set_cookie('name','thn')
            return res
    return render(request, 'login.html')

@login_ai
def home(request):
    return HttpResponse('登陆后才能查看')

@login_ai
def index(request):
    return HttpResponse('登陆后看')

posted @ 2022-05-23 21:43  笑舞狂歌  阅读(30)  评论(0编辑  收藏  举报