zoukankan      html  css  js  c++  java
  • 五十一、form组件,钩子函数,cookie,session,

    django form 组件
      
    注册功能
    1.渲染前端标签获取用户输入 》》》》》》 渲染标签
    2.获取用户输入船体到后端校验 》》》》》》 校验数据
    3.校验未通过展示错误信息 》》》》》》》》 展示信息

    校验数据(前后端都可以)
    校验前端后端都可以做,但是前端可以不做,后端必须做

    django form组件的三大功能
    1.渲染标签
    2.校验数据
    3.展示信息
    校验数据:
    第一步:写一个form类
     from django import forms
        class MyForm(forms.Form):
            name = forms.CharField(max_length=6, label="用户名")  # 最大为6位,不能超过
            password = forms.CharField(max_length=8, min_length=3, label="密码")  # 字段不能小于3大于8
            email = forms.EmailField(required=False, label="邮箱")  # required=False不做校

    第二部: 实例化form对象
    form_obj = MyForm({"name":"json","password":"123","email":"123@qq.com"})
       第三部:查看数据校验是否合法
    form_obj.is_valid() # 只有所有字段都通过才是True
    第四部:查看校验错误的信息
    form_obj.errors # 这个放到所有校验未通过的错误信息
    第五部:查看通过的信息
    form_obj.cleaned_data # 所有校验符合信息

    ps: form组件校验数据的规则从上往下一次取值校验
    校验通过的放到cleaned_data 中
    校验失败的放到form_obj.errors
    form 所有字段默认都是必须传值的(required=True),不校验改为false
    校验数据时候可以多传,多传的数据不会校验,也不会影响校验结果

    渲染标签
    form组件只帮你渲染获取用户输入的标签(input),不会帮你渲染提交按钮,需要手动添加

       def register(request):
        # 生成一个空对象,把对象传进去
           form_obj = MyForm()
           return render(request, "register.html", locals()
        <h1>第一种渲染方式</h1>
     {{ form_obj.name }}   {# 只表示name框 #}
     {{ form_obj.as_p}}   {# 把字段表格框全渲染出来 包括名字
     {{ form_obj.as_ul }}  {# 把字段表格框全渲染出来 包括名字,但是手写字母是大写

    <h1>第二种渲染方式</h1>
    <form action="">
                    <p>{{ form_obj.name.label }}:{{ form_obj.name }}</p>
                    <p>{{ form_obj.password.label }} :{{ form_obj.password }}</p>
                    <p>{{ form_obj.email.label }}:{{ form_obj.email }}</p>
                    <input type="submit" value="确认">
                </form>
     <h1>第三种渲染</h1>
                    {% for foo in form_obj %}
                        <p>{{ foo.label }}:{{ foo}}
                        </p>  {#  把三个框都渲染出来 foo 就像第一种传的方式#}
    
           前端取消校验
                <form action="" method="post" novalidate>
                只需要加上novalidate,取消校验

    form组件提交数据

      如果数据不合法,页面上会保留输入数据
      在使用form组件对模型表记性数据校验的时候,只需要保证字段一致
      那么在创建的对象的时候你就直接**form_obj.cleaned_data
    # 把数据添加到数据库
    def register(request):
           # 生成一个空对象,把对象传进去
           form_obj = MyForm()
           if request.method == "POST":
               print(request.POST)
               print(request.POST.get("name"))
               form_obj = MyForm(request.POST)  # 现在变成有值的对象
               # form_obj注意和if上面一样,重新把对象赋值,如果是错误下面不走,然后返回到前端
               if form_obj.is_valid():
                   print(form_obj.cleaned_data)  # {'name': 'json', 'password': '666', 'email': '123@qq.com'}
                   models.User.objects.create(**form_obj.cleaned_data)  # 打散后直接创建,不需要挨个获取了
                   return HttpResponse("ok")
    
           return render(request, "register.html", locals())
        前端展示错误信息:
         <form action="" method="post" novalidate>
               {% for foo in form_obj %}
                   <p>{{ foo.label }}:{{ foo}}
                   <span>{{ foo.errors.0 }}</span> {# 打印错误信息 #}
                   </p>  {#  把三个框都渲染出来 foo 就像第一种传的方式#}
               {% endfor %}
               <input type="submit">
           </form>
    #校验用户,设置条件
    class
    MyForm(forms.Form): name = forms.CharField(max_length=6, label="用户名", error_messages={ "mex_length": "用户名最长六位", "required": "用户名不能为空" }) # 最大为6位,不能超过 password = forms.CharField(max_length=8, min_length=3, label="确认密码") # 字段不能小于3大于8 ,确认密码 confirm_password = forms.CharField(max_length=8, min_length=3, label="密码") # 字段不能小于3大于8 email = forms.EmailField(label="邮箱", error_messages={ "required": "邮箱不能为空", "invalid": "邮箱格式不正确" }) # required=False不做校验
    # 钩子函数:
      简单说就对于校验通过的字段,再次进行校验
      # 局部钩子函数单个字段的校验利用局面)
        def clean_name(self):
            name = self.cleaned_data.get("name")
            if "666" in name:
                self.add_error("name", "sb666")  # 添加错误
            return name  # return还是要加上,考虑兼容
    # 全局钩子
    def clean(self):
        password = self.cleaned_data.get("password")
        confirm_password = self.cleaned_data.get("confirm_password")
        if not password == confirm_password:
            self.add_error("password", "两次密码不相等")
        return self.cleaned_data
    # 设置标签样式
     from django.forms import widgets
        password = forms.CharField(max_length=8, min_length=3, label="确认密码",widget=widgets.PasswordInput())  密文
        password = forms.CharField(max_length=8, min_length=3, label="确认密码",widget=widgets.PasswordInput(attrs={"class":"form_control c1"}))   样式

    #choices字段
    gender = forms.ChoiceField(
        choices=((1, ""), (2, ""), (3, "保密")),
        label="性别",
        initial=3, # 默认值
        widget=forms.widgets.RadioSelect()
    cookie
    保存在客户端浏览器上的键值对

    session
    保存在服务端上的键值对
    服务端产生随机的串返回给客户端,服务端找一个地方将串与对应的信息存起来(随机字符串:敏感信息)

    django
    return HttpResponse()
    return render()
    return redirect()

    obj = HttpResponse()
    return obj
    obj = render()
    return obj
    obj = redirect()
    return obj

    cookie使用方法
    设置cookie
    obj.set_cookie("name","json") # 给浏览器设置cookie
    获取cookie
    request.COOKIE.get("name")
    删除
    delete_cookie("user")
    删除cookie
    def logout(request):
    rep = redirect("/login/")
    rep.delete_cookie("user") # 删除
    return rep
    cookie装饰器:
    def login_auth(func):
        @wraps(func)
        def inner(request, *args, **kwargs):
            old_path = request.get_full_path()
            if request.COOKIES.get("name"):
                return func(request, *args, **kwargs)
            return redirect("/login/?next=%s" % old_path)  # 拿到之前访问路径
    
        return inner
    
    
    """1.想要登录之前,登录后返回当前你想要的的界面
       2.在装饰器上,把自己的路劲记录下来get请求
       3.当你登录过后,做一个判断,如果有值直接返回你想返回的界面,
       4.如果没有值,直接跳转到主页面"""
    
    
    def index(request):
        print(request.COOKIES.get("name"))
        if request.COOKIES.get("name"):
            return HttpResponse("我是index页面,只有登录才能展示")
        return redirect("/login/")
    
    
    @login_auth
    def home(request):
        return HttpResponse("home.去死吧")
    
    
    @login_auth
    def nice(request):
        return HttpResponse("nice,总有刁民想害朕")
    装饰器
    session
    设置session
    request.session["name"] = "json"
    # 1.先生成一个随机的字符串
    # 2.在django session表中存储该随机字符串与数据的记录
    # 3.将随机的字符串发送给客户端浏览器
    获取session
    request.session.get("name")
    # 1.django自动获取浏览器字符串 取django session表中里面进行比对
    # 2. 如果比对成功 会将当前对应的数据赋值给request.session
    # 3. 通过request.session 操作该数据(数据不存在,也不会影响业务逻辑)

    当后端执行request.session["name"] = "json",会自动把数据存储到数据库中django_session表中,第一个表示随机的串,
    第二个是加密后的键值对,第三个是超时时间默认14天, 浏览器会设置一个键为sessionid来存放session值,只要服务端设置成功,浏览器
    也会自动保存
    ps:传给客户端的是session值是表中第一个数据,然后进行比对,看是否登录

    django默认的session存活的时间是两周14天
    一个浏览器占一行

    # 删除当前会话的所有Session数据(删除数据库中)
    request.session.delete()
      
    # 删除当前的会话数据并删除会话的Cookie。(删除两边的)
    request.session.flush()

    # 设置会话Session和Cookie的超时时间
    request.session.set_expiry(value)
    * 如果value是个整数,session会在些秒数后失效。
    * 如果value是个datatime或timedelta,session就会在这个时间后失效。
    * 如果value是0,用户关闭浏览器session就会失效。
    * 如果value是None,session会依赖全局session失效策略。
    CBV加装饰器
     from django.utils.decorators import method_decorator
    
        # 类装饰器
        # @method_decorator(login_auth, name="get")  # 第二种方法
        class MyHome(View):
            @method_decorator(login_auth)  # 第三种方法  get和post都会被装饰
            def dispatch(self, request, *args, **kwargs):
                super().dispatch(request, *args, **kwargs)
    
            # @method_decorator(login_auth)  # 第一种方法
            def get(self, request):
                return HttpResponse("get")
    
            def post(self, request):
                return HttpResponse("post")



  • 相关阅读:
    树分治 poj 1741
    堆 poj 2010
    堆 poj 2442
    堆的基本操作
    状态压缩codeforces 11 D
    状态压缩 CSU1129 送货到家
    炮兵阵地 POJ 1185
    状态压缩 HDU4539 郑厂长系列故事——排兵布阵
    状态压缩 HDU 3182
    android手势创建及识别
  • 原文地址:https://www.cnblogs.com/wukai66/p/11604430.html
Copyright © 2011-2022 走看看