zoukankan      html  css  js  c++  java
  • Django补充

    django页面渲染具体流程

      在django的页面渲染中,下面这段程序

    def test1(request):
        return render(request,'aa.html',{'data':'wusir'})

      等同于

    from django.template import loader
    def test1(request):
        html = loader.get_template('aa.html')
        html_str = html.render({'data':'wusir'})
        return HttpResponse(html_str)

    django中自定义simple_tag

      1、在app目录下创建一个文件夹名字叫templatetags,名字不能改,在该文件夹下随便建一个xxx.py文件,写入以下代码

    from django import template
    register = template.Library()
    @register.simple_tag
    def func(a1,a2): #(参数任意多)
    .......

      2、在前端页面的顶部写上{% load xxx %},然后就可以使用后端所定义的函数{% func 1 2 %}
    PS:simple_tag不能作为if后面的判断条件,但是参数任意多

    django中自定义filter

      1、在app目录下创建一个文件夹名字叫templatetags,名字不能改,在该文件夹下随便建一个xxx.py文件,写入以下代码

    from django import template
    register = template.Library()
    @register.filter
    def func(a1,a2): #(参数最多两个)
    .......

      2、在前端页面的顶部写上{% load xxx %},然后就可以使用{ { xxx|func:yyy } } ,xxx,yyy对应两个参数 ,如果函数只有一个
    参数,func后面的冒号和后面的参数就不用写了。
    PS:能作为if后面的判断条件,但是参数最多两个,并且冒号后面不能加空格

    基于FBV、CBV的用户认证装饰器

      FBV

    def login(request):
        if request.method == 'GET':
            return render(request,'login.html')
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            obj = User.objects.filter(username=username).first()
            if not obj:
                return redirect('/app/login/')
            if password == obj.pwd:
                res = redirect('/app/index/')
                res.set_cookie('username',username)
                return res
            else:
                return redirect('/app/login/')
    
    def auth(func):
        def inner(request,*args,**kwargs):
            res = request.COOKIES.get('username')
            if not res:
                return redirect('/app/login/')
            return func(request,*args,**kwargs)
        return inner
    
    @auth
    def index(request):
        res = request.COOKIES.get('username')
        return render(request,'index.html',{'data':res})
    views.py

      CBV

    def login(request):
        if request.method == 'GET':
            return render(request,'login.html')
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            obj = User.objects.filter(username=username).first()
            if not obj:
                return redirect('/app/login/')
            if password == obj.pwd:
                res = redirect('/app/index/')
                res.set_cookie('username',username)
                return res
            else:
                return redirect('/app/login/')
    
    def auth(func):
        def inner(request,*args,**kwargs):
            res = request.COOKIES.get('username')
            if not res:
                return redirect('/app/login/')
            return func(request,*args,**kwargs)
        return inner
    
    
    from django import views
    from django.utils.decorators import method_decorator
    #三种方式:在每个函数上加,在dispatch上加,在类上加装饰器
    method_decorator(auth,name='dispatch')
    class Order(views.View):
        # @method_decorator(auth)
        # def dispatch(self, request, *args, **kwargs):
        #     return super(Order, self).dispatch(request, *args, **kwargs)
    
        # @method_decorator(auth)
        def get(self,request):
            res = request.COOKIES.get('username')
            # if not res:
            #     return redirect('/app/login/')
            return render(request,'index.html',{'data':res})
    views.py

    django之Form组件

    django中的Form一般有两种功能:

    • 输入html
    • 验证用户输入
    from django import forms
    class FM(forms.Form):
        user = forms.CharField(error_messages={'required':'用户名不能为空'})
        email = forms.CharField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'})
        pwd = forms.CharField(max_length=12,min_length=6,error_messages={'required':'密码不能为空','max_length':
                                                                         '最大长度不能超过12','min_length':
                                                                         '最小长度不能低于6'})
    
    def test_form(request):
        if request.method == 'GET':
            obj = FM()
            return render(request,'test_form.html',{'obj':obj})
        elif request.method == 'POST':
            obj = FM(request.POST)
            r1 = obj.is_valid()
            if r1:
                print(obj.cleaned_data)
                Person.objects.create(**obj.cleaned_data)
            else:
                print(obj.errors)
                # print(obj.errors.as_json())
                # print(obj.errors['user'][0])
                return render(request,'test_form.html',{'obj':obj})
            return render(request,'test_form.html')
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    {#<form action="/app/test_form/" method="post">#}
    {#    {% csrf_token %}#}
    {#    <p><input type="text" name="user">{{ obj.errors.user.0 }}</p>#}
    {#    <p><input type="email" name="email">{{ obj.errors.email.0 }}</p>#}
    {#    <p><input type="password" name="pwd">{{ obj.errors.pwd.0 }}</p>#}
    {#    <input type="submit" value="提交">#}
    {#</form>#}
    
    {#<form action="/app/test_form/" method="post">#}
    {#    {% csrf_token %}#}
    {#    <p>{{ obj.user }}{{ obj.errors.user.0 }}</p>#}
    {#    <p>{{ obj.email }}{{ obj.errors.email.0 }}</p>#}
    {#    <p>{{ obj.pwd }}{{ obj.errors.pwd.0 }}</p>#}
    {#    <input type="submit" value="提交">#}
    {#</form>#}
    
    <form action="/app/test_form/" method="post">
        {% csrf_token %}
    {#    方式一#}
    {#    {{ obj.as_p }}#}
    {#    方式二#}
    {#    {{ obj.as_ul }}#}
    {#    方式三#}
        <table>
        {{ obj.as_table }}
        </table>
        <input type="submit" value="提交">
    </form>
    
    </body>
    </html>
    前端页面

     PS:以后使用的时候将forms改成fields,fields里面有一个插件widget,可以定制样式

    from django import forms
    from django.forms import fields
    from django.forms import widgets
    class FM(forms.Form):
        user = fields.CharField(error_messages={'required':'用户名不能为空'},widget=widgets.Textarea(attrs={
            'class':'c1'
        }))
    
        email = fields.CharField(error_messages={'required':'邮箱不能为空','invalid':'邮箱格式错误'},widget=widgets.PasswordInput)
        pwd = fields.CharField(max_length=12,min_length=6,error_messages={'required':'密码不能为空','max_length':
                                                                         '最大长度不能超过12','min_length':
                                                                         '最小长度不能低于6'})
    
    def test_form(request):
        if request.method == 'GET':
            obj = FM()
            return render(request,'test_form.html',{'obj':obj})
        elif request.method == 'POST':
            obj = FM(request.POST)
            r1 = obj.is_valid()
            if r1:
                print(obj.cleaned_data)
                Person.objects.create(**obj.cleaned_data)
            else:
                print(obj.errors)
                # print(obj.errors.as_json())
                # print(obj.errors['user'][0])
                return render(request,'test_form.html',{'obj':obj})
            return render(request,'test_form.html')
    views.py

     详细内容参考:https://www.cnblogs.com/wupeiqi/articles/6144178.html

    跨站请求伪造

    一、简介

      django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

    全局:

      中间件 django.middleware.csrf.CsrfViewMiddleware

    局部:

    • @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
    • @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

    注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

    二、应用

    1、普通表单

     html中设置Token:
    {% csrf_token %}
    View Code

    2、Ajax请求

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="/app/test1/" method="post">
        {% csrf_token %}
        <input type="text" placeholder="用户名" name="user">
        <input type="password" placeholder="密码" name="pwd">
        <input type="submit" value="提交">
        <input id="btn" type="button" value="按钮">
    </form>
    
    <script src="/static/jquery-1.12.4.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    <script>
        $('#btn').click(function () {
    {#        给除GET|HEAD|OPTIONS|TRACE几个方法以外的方法全部设置csrftoken#}
    {#        过滤方法#}
            var csrftoken = $.cookie('csrftoken');
            function csrfSafeMethod(method) {
                return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
            }
    {#         设置csrftoken#}
            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
            });
    
            $.ajax({
                url:'/app/test1/',
                type:'GET',
                data:{'user':'alex'},
    {#            headers: {'X-CSRFtoken': $.cookie('csrftoken')},      单个ajax请求设置csrftoken#}
                success:function (res) {
    
                }
            })
        })
    </script>
    
    </body>
    </html>
    View Code
  • 相关阅读:
    [其他]将Windows Terminal添加到右键菜单
    [VS Code]在自己的Ubuntu服务器上构建VSCode Online
    [Go]goFileView-基于Golang的在线Office全家桶预览
    [Go]基于Go语言的Web路由转发,多个网站共享一个端口(新版本,支持WebSocket)
    [WSL]在Windows10子系统里安装运行桌面(xUbuntu)
    [Go]使用Golang对鸢尾花数据集进行k-means聚类
    [Python+JavaScript]JS调用摄像头并拍照,上传至tornado后端并转换为PIL的Image
    [Python]Python基于OpenCV批量提取视频中的人脸并保存
    [WSL]Windows10 Ubuntu子系统编译安装线程安全版LAMP
    [Go]基于Go语言的Web路由转发,多个网站共享一个端口(存在问题,已经抛弃,新解决方案请看新博客)
  • 原文地址:https://www.cnblogs.com/wusir66/p/10183079.html
Copyright © 2011-2022 走看看