zoukankan      html  css  js  c++  java
  • 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表中,保存的数据 可以在后端任意位置获取到

     

  • 相关阅读:
    Asp.Net Web API 2第八课——Web API 2中的属性路由
    Asp.Net Web API 2第七课——Web API异常处理
    Asp.Net Web API 2第六课——Web API路由和动作选择
    Asp.Net Web API 2第五课——Web API路由
    开始学习python
    BMI 小程序 购物车
    深浅copy 文件操作
    字典 dict 集合set
    基本数据类型 (str,int,bool,tuple,)
    python 运算符
  • 原文地址:https://www.cnblogs.com/huaiXin/p/11581023.html
Copyright © 2011-2022 走看看