• django之forms组件,cookie与session


    多对多表的创建

    1 全自动

    优点: 不需要手动创建第三张表, orm查询简单

    缺点: 第三张表无法扩展.当第三张表需要增加字段是无法操作.

    # 全自动创建第三张表, 利用①语句经行创建.
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=8,decimal_places=2)
        authors = models.ManyToManyField(to='Author')  #
    class Author(models.Model):
        name = models.CharField(max_length=32)

    2 手动创建

    优点: 第三张表可以扩展

    缺点: 查询不方便, 当连表查询的时候复杂

    # 手动创建第三张关系表.
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=8,decimal_places=2)
    ​
    class Author(models.Model):
        name = models.CharField(max_length=32)
                    
    class Book2Author(models.Model):
        book = models.ForeignKey(to='Book')
        author = models.ForeignKey(to='Author')
        create_time = models.DateField(auto_now_add=True)

    3 半自动

    结合全自动与手动的优点

    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=8,decimal_places=2)
        authors =models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author'))
        # through 告诉django orm 书籍表和作者表的多对多关系是通过Book2Author来记录的
        # through_fields 告诉django orm记录关系时用过Book2Author表中的book字段和author字段来#记录的
        # 注意 这种情况下不支持 add, set, remove, clear等语法
        
    class Author(models.Model):
        name = models.CharField(max_length=32)
        through_fields=('author', 'book')
    ​
    class Book2Author(models.Model):
        book = models.ForeignKey(to='Book')
        author = models.ForeignKey(to='Author')
        create_time = models.DateField(auto_now_add=True)

     

    Django中forms组件

    forms组件

    针对于django前端的form表单进行处理.处理目的围绕三个方面:1,渲染页面. 2, 数据效验. 3 展示数据

    2,forms组件基本用法

    1, 首先调用forms组件

    from django import forms

    2, 自定义类

    这个类是forms组件类,每个属性就是要校验的字段, 字段内部,有限制条件.如:max_length=8,最大长度为8.

    EmailField()这个默认限定格式是邮件格式.

    class MyForms(forms.Form):
        username = forms.CharField(max_length=8, min_length=3, )
        password = forms.CharField(max_length=8, min_length=3)
        email = forms.EmailField()

    限制条件的属性修改

    限制条件是可以有其他修改,比如报错信息, 正则匹配, 控制标签属性等

    # widget        控制标签属性和样式
    widget=widgets.PasswordInput()
    # 控制标签属性
    widget=widgets.PasswordInput(attrs={'class':'form-control c1 c2','username':'jason'})
    ​
    # 正则匹配
    from django.core.validators import RegexValidator
    phone = forms.CharField(
        validators = [RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '必须以数字159开头')]
    )

    钩子函数(HOOK)

    是组件类中的函数,一种是局部函数,一种是全局函数.

    
    
      # 局部钩子(针对某一个字段做额外的校验)
        def clean_username(self):
            username = self.cleaned_data.get('username')
            if '111' in username:
                self.add_error('username', '什么鬼密码!重来')
            return username
    ​
        # 全局钩子(针对多个字段做额外的校验)
        def clean(self):
            password = self.cleaned_data.get('password')
            if '111' in password:
                self.add_error('password', '什么鬼密码')
            return self.cleaned_data

    前端显示效果

    调试组件类

    在pycharm中python Console经行组件调试

    from app01 import views  # 导入调试模块
    form_obj = views.MyForms({'username':'meKing', 'password': '15523', 'email':'123456@qq.com'})   # 实例化组件类,得到对象
    form_obj.errors  # 错误信息
    # 结果: {}
    form_obj.is_valid() # 是否正确
    # 结果: True
    form_obj.cleaned_data  # 正确信息内容
    # {'username': 'meKing', 'password': '15523', 'email': '123456@qq.com'}

    forms组件api

    def login(request):
        obj = MyForms()
        if request.method == 'POST':
            obj = MyForms(request.POST)
        return render(request, 'login.html', locals())

    前端页面

    <form action="" method="post" novalidate>   // novalidate: 取消前端校验
        {% for foo in obj %}
            <p>
                {{ foo.label }}:{{ foo }}
                <span>{{ foo.errors.0 }}</span>  // 显示报错信息
            </p>
        {% endfor %}
        <input type='submit'>
    </form>

    ps: 自定义类中所有字段都要出传值比对.

    forms组件其他信息

    常用字段与插件

    创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;

    initial

    初始值,input框里面的初始值。

    class LoginForm(forms.Form):
        username = forms.CharField(
            min_length=8,
            label="用户名",
            initial="张三"  # 设置默认值
        )
        pwd = forms.CharField(min_length=6, label="密码")

    error_messages

    重写错误信息。

    class LoginForm(forms.Form):
        username = forms.CharField(
            min_length=8,
            label="用户名",
            initial="张三",
            error_messages={
                "required": "不能为空",
                "invalid": "格式错误",
                "min_length": "用户名最短8位"
            }
        )
        pwd = forms.CharField(min_length=6, label="密码")

    password

    class LoginForm(forms.Form):
        ...
        pwd = forms.CharField(
            min_length=6,
            label="密码",
            widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
        )

    radioSelect

    单radio值为字符串

    class LoginForm(forms.Form):
        username = forms.CharField(
            min_length=8,
            label="用户名",
            initial="张三",
            error_messages={
                "required": "不能为空",
                "invalid": "格式错误",
                "min_length": "用户名最短8位"
            }
        )
        pwd = forms.CharField(min_length=6, label="密码")
        gender = forms.fields.ChoiceField(
            choices=((1, "男"), (2, "女"), (3, "保密")),
            label="性别",
            initial=3,
            widget=forms.widgets.RadioSelect()
        )

    单选Select

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

    多选Select

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

    单选checkbox

    class LoginForm(forms.Form):
        ...
        keep = forms.ChoiceField(
            label="是否记住密码",
            initial="checked",
            widget=forms.widgets.CheckboxInput()
        )

    多选checkbox

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

    choice字段注意事项

    在使用选择标签时,需要注意choices的选项可以配置从数据库中获取,但是由于是静态字段 获取的值无法实时更新,需要重写构造方法从而实现choice实时更新。

     

    方式一
    from django.forms import Form
    from django.forms import widgets
    from django.forms import fields
    ​
     
    class MyForm(Form):
     
        user = fields.ChoiceField(
            # choices=((1, '上海'), (2, '北京'),),
            initial=2,
            widget=widgets.Select
        )
     
        def __init__(self, *args, **kwargs):
            super(MyForm,self).__init__(*args, **kwargs)
            # self.fields['user'].choices = ((1, '上海'), (2, '北京'),)
            #
            self.fields['user'].choices = models.Classes.objects.all().values_list('id','caption')
    方式二:
    from django import forms
    from django.forms import fields
    from django.forms import models as form_model
    ​
     
    class FInfo(forms.Form):
        authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())  # 多选
        # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())  # 单选

    cookie与session

    由于HTTP协议是无状态的, 无法记录用户状态.cookie与session是记录用户状态

    cookie就是保存在客户端浏览器上的键值对. 工作原理:当你登陆成功之后 浏览器上会保存一些信息
    下次再访问的时候 就会带着这些信息去访问服务端  服务端通过这些信息来识别出你的身份, cookie虽然是写在客户端浏览器上的  但是是服务端设置的, 浏览器可以选择不服从命令 禁止写cookie.

    session就是保存在服务器上的键值对, session虽然是保存在服务器上的键值对, 但是它是依赖于cookie工作的, 服务端返回给浏览器一个随机的字符串, 浏览器以键值对的形式保存, sessionid:随机字符串, 浏览器在访问服务端的时候  就会将随机字符串携带上, 后端获取随机串与后端的记录的做比对
    随机字符串1:数据1
    随机字符串2:数据2

    设置cookie利用的就是HttpResponse对象

     obj1.set_cookie('k1','v1')
    
    

    获取cookie

    request.COOKIE.get()

    删除cookie

    obj1.delete_cookie("k1")

    设置超时时间
    max_age=None, 超时时间
    expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)

    登陆功能

    设置session

    request.session['name'] = 'jason'

    """
    上面这一句话发生了三件事
    1.django 内部自动生成一个随机字符串
    2.将随机字符串和你要保存的数据 写入django_session表中(现在内存中生成一个缓存记录 等到经过中间件的时候才会执行)
    3.将产生的随机字符串发送给浏览器写入cookie
    sessionid:随机字符串
    """
    获取session

    request.session.get('name')

    """
    上面这一句话发生了三件事
    1.django内部会自动从请求信息中获取到随机字符串
    2.拿着随机字符串去django_session表中比对
    3.一旦对应上了就将对应的数据解析出来放到request.session中
    """

    django session默认的超时时间是14天

    django_session表中的一条记录针对一个浏览器

    删除当前会话的所有Session数据

    request.session.delete()  # 删除的是浏览器的sessionid信息
      删除当前的会话数据并删除会话的Cookie。

    request.session.flush()  # 将浏览器和服务端全部删除
    这用于确保前面的会话数据不可以再次被用户的浏览器访问
    例如,django.contrib.auth.logout() 函数中就会调用它。

    设置会话Session和Cookie的超时时间

    request.session.set_expiry(value)

    • 如果value是个整数,session会在些秒数后失效。

      • 如果value是个datatime或timedelta,session就会在这个时间后失效。

      • 如果value是0,用户关闭浏览器session就会失效。

      • 如果value是None,session会依赖全局session失效策略

    总结:你在后期可以将一些数据保存到session表中,保存的数据 可以在后端任意位置获取到

     

  • 相关阅读:
    2020年12月学习记录
    Data Protection Application Programming Interface滥用攻击
    另类的缓存凭证收集
    js获取地址栏参数,携带参数跳转页面
    用JS获取地址栏参数的方法
    解决vue加载时闪烁
    vue-cli-service build 不同环境配置
    vite创建vue3.x项目报404的解决方案
    后端开发完接口才给出接口文档,合理吗?
    API研发实现规范化管理的价值
  • 原文地址:https://www.cnblogs.com/huaiXin/p/11581023.html
Copyright © 2020-2023  润新知