Django框架(三)

0627内容:

上节回顾:
    1. FBV、CBV
    
    2. 数据库操作
        class UserGroup(models.Model):
            """
            部门 3
            """
            title = models.CharField(max_length=32)
        class UserInfo(models.Model):
            """
            员工4
            """
            nid = models.BigAutoField(primary_key=True)
            user = models.CharField(max_length=32)
            password = models.CharField(max_length=64)
            age = models.IntegerField(default=1)
            # ug_id 1
            ug = models.ForeignKey("UserGroup",null=True)
        - 跨表
            正:
                
                1. q = UserInfo.objects.all().first()
                    q.ug.title
                    
                2. 
                    UserInfo.objects.values('nid','ug_id')              
                    UserInfo.objects.values('nid','ug_id','ug__title')  
                
                3. UserInfo.objects.values_list('nid','ug_id','ug__title')
            反:
                1. 小写的表名_set
                    obj = UserGroup.objects.all().first()
                   result = obj.userinfo_set.all() [userinfo对象,userinfo对象,]
                   
                2. 小写的表名
                    v = UserGroup.objects.values('id','title')          
                    v = UserGroup.objects.values('id','title','小写的表名称')          
                    v = UserGroup.objects.values('id','title','小写的表名称__age')          
                    
                3. 小写的表名
                    v = UserGroup.objects.values_list('id','title')          
                    v = UserGroup.objects.values_list('id','title','小写的表名称')          
                    v = UserGroup.objects.values_list('id','title','小写的表名称__age')    

            PS: 前面的所有数据都会显示
            
        - 其他:
            UserInfo.objects.all()
            UserInfo.objects.filter(id=1,id=2)
            UserInfo.objects.all().first()
            UserInfo.objects.all().count()
            UserInfo.objects.all().update()
            UserInfo.objects.all().delete()
            UserInfo.objects.all()[1:19]
            跨表:
                正向:
                    xxxx.filter(ut__title='超级用户').values('id','name','ut__title')
                反向:
                    xxxx.filter(表名称__title='超级用户').values('id','name','表名称__title')
            
    3. 分页组件
        - 内置
        - 自定义
上节回顾(0626)
1. Django ORM操作
            # 1.增删改查
            # 2. 一般:
                # models.UserInfo.objects.filter(id__gt=1)
                # models.UserInfo.objects.filter(id__lt=1)
                # models.UserInfo.objects.filter(id__lte=1)
                # models.UserInfo.objects.filter(id__gte=1)
                # models.UserInfo.objects.filter(id__in=[1,2,3])
                # models.UserInfo.objects.filter(id__range=[1,2])
                # models.UserInfo.objects.filter(name__startswith='xxxx')
                # models.UserInfo.objects.filter(name__contains='xxxx')
                # models.UserInfo.objects.exclude(id=1)
            # 3. 排序
                user_list = models.UserInfo.objects.all().order_by('-id','name')
            
            # 4. 分组
                from django.db.models import Count,Sum,Max,Min
                # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id'))
                # print(v.query)
                # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)
                # print(v.query)
                # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)
                # print(v.query)
                
            
            
            # 5. F,更新时用于获取原来的值
                # from django.db.models import F,Q
                # models.UserInfo.objects.all().update(age=F("age")+1)
            
            # 6. Q,用于构造复杂查询条件
                # 应用一:
                        # models.UserInfo.objects.filter(Q(id__gt=1))
                        # models.UserInfo.objects.filter(Q(id=8) | Q(id=2))
                        # models.UserInfo.objects.filter(Q(id=8) & Q(id=2))
                # 应用二:
                        # q1 = Q()
                        # q1.connector = 'OR'
                        # q1.children.append(('id__gt', 1))
                        # q1.children.append(('id', 10))
                        # q1.children.append(('id', 9))
                        #
                        #
                        # q2 = Q()
                        # q2.connector = 'OR'
                        # q2.children.append(('c1', 1))
                        # q2.children.append(('c1', 10))
                        # q2.children.append(('c1', 9))
                        #
                        # q3 = Q()
                        # q3.connector = 'AND'
                        # q3.children.append(('id', 1))
                        # q3.children.append(('id', 2))
                        # q2.add(q3,'OR')
                        #
                        # con = Q()
                        # con.add(q1, 'AND')
                        # con.add(q2, 'AND')
                        
                        # models.UserInfo.objects.filter(con)
            
            # 7. extra, 额外查询条件以及相关表,排序
            
                models.UserInfo.objects.filter(id__gt=1)
                models.UserInfo.objects.all() 
                # id name age ut_id
            
            
                models.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
                # a. 映射
                    # select 
                    # select_params=None
                    # select 此处 from 表
                
                # b. 条件
                    # where=None
                    # params=None,
                    # select * from 表 where 此处
                
                # c. 表
                    # tables
                    # select * from 表,此处
                    
                # c. 排序
                    # order_by=None
                    # select * from 表 order by 此处
                
                
                models.UserInfo.objects.extra(
                    select={'newid':'select count(1) from app01_usertype where id>%s'},
                    select_params=[1,],
                    where = ['age>%s'],
                    params=[18,],
                    order_by=['-age'],
                    tables=['app01_usertype']
                )
                """
                select 
                    app01_userinfo.id,
                    (select count(1) from app01_usertype where id>1) as newid
                from app01_userinfo,app01_usertype
                where 
                    app01_userinfo.age > 18
                order by 
                    app01_userinfo.age desc
                """
                
                result = models.UserInfo.objects.filter(id__gt=1).extra(
                    where=['app01_userinfo.id < %s'],
                    params=[100,],
                    tables=['app01_usertype'],
                    order_by=['-app01_userinfo.id'],
                    select={'uid':1,'sw':"select count(1) from app01_userinfo"}
                )
                print(result.query)
                # SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC
            
            # 8. 原生SQL语句
            
                from django.db import connection, connections
                
                cursor = connection.cursor() # connection=default数据
                cursor = connections['db2'].cursor()
                
                cursor.execute("""SELECT * from auth_user where id = %s""", [1])
                
                row = cursor.fetchone()
                row = cursor.fetchall()
                
                
                - extra
                - 原生SQL语句
                - raw
                    result = models.UserInfo.objects.raw('select * from userinfo')
                    [obj(UserInfo),obj,]
                    result = models.UserInfo.objects.raw('select id,1 as name,2 as age,4 as ut_id from usertype')
                    [obj(UserInfo),obj,]
                    
                    v1 = models.UserInfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map)
                    
            # 9. 简单的操作
                http://www.cnblogs.com/wupeiqi/articles/6216618.html
1. Django ORM操作
2. xss攻击
        - 慎用 safe和mark_safe
        - 非要用,一定要过滤关键字
2.xss攻击

XSS攻击:

"""djangoxss URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^comment/', views.comment),    #输入内容
    url(r'^index/', views.index),    #查看内容
    url(r'^test/', views.test),    #测试页
]
urls.py
from django.shortcuts import render
from django.utils.safestring import mark_safe
# Create your views here.
msg = []
def comment(request):
    if request.method == "GET":
        return render(request,'comment.html')
    else:
        v = request.POST.get('content')
        if "script" in v:
            return render(request,'comment.html',{'error':'小比崽子还黑我'})
        else:
            msg.append(v)
            return render(request,'comment.html')

def index(request):
    return render(request,'index.html',{'msg':msg})

def test(request):
    temp = "<a href='http://www.baidu.com'>百度</a>"
    newtemp = mark_safe(temp)
    # return render(request,'test.html',{'temp':temp})
    return render(request,'test.html',{'temp':newtemp})
views.py

template文件(html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

<form method="POST" action="/comment/">
    <input type="text" name="content" />
    <input type="submit" value="提交" />{{ error }}

</form>

</body>
</html>
comment.html 提交内容
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <h1>评论</h1>
    {% for item in msg %}
        <div>{{ item|safe }}</div> #加上safe代表标记提交的数据时安全的
    {% endfor %}
</body>
</html>
index.html 查看comment提交的内容
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    {{ temp|safe }}

</body>
</html>
test.html 测试页

xss总结:

XSS注入攻击(跨站脚本攻击)
    for(var i=0,j=0;i<999,j<9999;i++,j++)
    {
      window.alert("");
    }

    <html>
    <head>text</head>
    <body>
    <form>
    <input type="text" name="text">
    </form>
    </body>
    </html>
        <script>
        alert('sb')
        </script>
        
<script>
获取本地cookie,将cookie发送至www.xxx.com(黑客的网址,把本地的隐私cookie发送给黑客)
</script>

    <h1>评论</h1>
    {% for item in msg %}
        <div>{{ item|safe }}</div>
    {% endfor %}
    写上safe会出问题
    safe是别人能随便添加或者随便写的,一定要对特殊字符做过滤
<script>alert('sb')</script> 会弹出一个框,如果是循环会撑爆浏览器
View Code

标记某个字符串或者标签是安全的:
两种方式:
    1.前端页面的字符串{{ temp|safe}}加上 |safe
    2.from django.utils.safestring import mark_safe
      def test(request):
      temp = "<a href='http://www.baidu.com'>百度</a>"
      newtemp = mark_safe(temp)
      # return render(request,'test.html',{'temp':temp})
    return render(request,'test.html',{'temp':newtemp})
xss攻击:
慎用safe和mark_safe
非要用,一定要在提交数据时过滤关键字

上节回顾:
    1. FBV、CBV
    
    2. 数据库操作
        class UserGroup(models.Model):
            """
            部门 3
            """
            title = models.CharField(max_length=32)
        class UserInfo(models.Model):
            """
            员工4
            """
            nid = models.BigAutoField(primary_key=True)
            user = models.CharField(max_length=32)
            password = models.CharField(max_length=64)
            age = models.IntegerField(default=1)
            # ug_id 1
            ug = models.ForeignKey("UserGroup",null=True)
        - 跨表
            正:
                
                1. q = UserInfo.objects.all().first()
                    q.ug.title
                    
                2. 
                    UserInfo.objects.values('nid','ug_id')              
                    UserInfo.objects.values('nid','ug_id','ug__title')  
                
                3. UserInfo.objects.values_list('nid','ug_id','ug__title')
            反:
                1. 小写的表名_set
                    obj = UserGroup.objects.all().first()
                   result = obj.userinfo_set.all() [userinfo对象,userinfo对象,]
                   
                2. 小写的表名
                    v = UserGroup.objects.values('id','title')          
                    v = UserGroup.objects.values('id','title','小写的表名称')          
                    v = UserGroup.objects.values('id','title','小写的表名称__age')          
                    
                3. 小写的表名
                    v = UserGroup.objects.values_list('id','title')          
                    v = UserGroup.objects.values_list('id','title','小写的表名称')          
                    v = UserGroup.objects.values_list('id','title','小写的表名称__age')    

            PS: 前面的所有数据都会显示
            
        - 其他:
            UserInfo.objects.all()
            UserInfo.objects.filter(id=1,id=2)
            UserInfo.objects.all().first()
            UserInfo.objects.all().count()
            UserInfo.objects.all().update()
            UserInfo.objects.all().delete()
            UserInfo.objects.all()[1:19]
            跨表:
                正向:
                    xxxx.filter(ut__title='超级用户').values('id','name','ut__title')
                反向:
                    xxxx.filter(表名称__title='超级用户').values('id','name','表名称__title')
            
    3. 分页组件
        - 内置
        - 自定义
上节回顾(0627)
今日任务:
    1. Django ORM操作
            # 1.增删改查
            # 2. 一般:
                # models.UserInfo.objects.filter(id__gt=1)
                # models.UserInfo.objects.filter(id__lt=1)
                # models.UserInfo.objects.filter(id__lte=1)
                # models.UserInfo.objects.filter(id__gte=1)
                # models.UserInfo.objects.filter(id__in=[1,2,3])
                # models.UserInfo.objects.filter(id__range=[1,2])
                # models.UserInfo.objects.filter(name__startswith='xxxx')
                # models.UserInfo.objects.filter(name__contains='xxxx')
                # models.UserInfo.objects.exclude(id=1)
            # 3. 排序
                user_list = models.UserInfo.objects.all().order_by('-id','name')
            
            # 4. 分组
                from django.db.models import Count,Sum,Max,Min
                # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id'))
                # print(v.query)
                # v =models.UserInfo.objects.values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)
                # print(v.query)
                # v =models.UserInfo.objects.filter(id__gt=2).values('ut_id').annotate(xxxx=Count('id')).filter(xxxx__gt=2)
                # print(v.query)
                
            
            
            # 5. F,更新时用于获取原来的值
                # from django.db.models import F,Q
                # models.UserInfo.objects.all().update(age=F("age")+1)
            
            # 6. Q,用于构造复杂查询条件
                # 应用一:
                        # models.UserInfo.objects.filter(Q(id__gt=1))
                        # models.UserInfo.objects.filter(Q(id=8) | Q(id=2))
                        # models.UserInfo.objects.filter(Q(id=8) & Q(id=2))
                # 应用二:
                        # q1 = Q()
                        # q1.connector = 'OR'
                        # q1.children.append(('id__gt', 1))
                        # q1.children.append(('id', 10))
                        # q1.children.append(('id', 9))
                        #
                        #
                        # q2 = Q()
                        # q2.connector = 'OR'
                        # q2.children.append(('c1', 1))
                        # q2.children.append(('c1', 10))
                        # q2.children.append(('c1', 9))
                        #
                        # q3 = Q()
                        # q3.connector = 'AND'
                        # q3.children.append(('id', 1))
                        # q3.children.append(('id', 2))
                        # q2.add(q3,'OR')
                        #
                        # con = Q()
                        # con.add(q1, 'AND')
                        # con.add(q2, 'AND')
                        
                        # models.UserInfo.objects.filter(con)
            
            # 7. extra, 额外查询条件以及相关表,排序
            
                models.UserInfo.objects.filter(id__gt=1)
                models.UserInfo.objects.all() 
                # id name age ut_id
            
            
                models.UserInfo.objects.extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
                # a. 映射
                    # select 
                    # select_params=None
                    # select 此处 from 表
                
                # b. 条件
                    # where=None
                    # params=None,
                    # select * from 表 where 此处
                
                # c. 表
                    # tables
                    # select * from 表,此处
                    
                # c. 排序
                    # order_by=None
                    # select * from 表 order by 此处
                
                
                models.UserInfo.objects.extra(
                    select={'newid':'select count(1) from app01_usertype where id>%s'},
                    select_params=[1,],
                    where = ['age>%s'],
                    params=[18,],
                    order_by=['-age'],
                    tables=['app01_usertype']
                )
                """
                select 
                    app01_userinfo.id,
                    (select count(1) from app01_usertype where id>1) as newid
                from app01_userinfo,app01_usertype
                where 
                    app01_userinfo.age > 18
                order by 
                    app01_userinfo.age desc
                """
                
                result = models.UserInfo.objects.filter(id__gt=1).extra(
                    where=['app01_userinfo.id < %s'],
                    params=[100,],
                    tables=['app01_usertype'],
                    order_by=['-app01_userinfo.id'],
                    select={'uid':1,'sw':"select count(1) from app01_userinfo"}
                )
                print(result.query)
                # SELECT (1) AS "uid", (select count(1) from app01_userinfo) AS "sw", "app01_userinfo"."id", "app01_userinfo"."name", "app01_userinfo"."age", "app01_userinfo"."ut_id" FROM "app01_userinfo" , "app01_usertype" WHERE ("app01_userinfo"."id" > 1 AND (app01_userinfo.id < 100)) ORDER BY ("app01_userinfo".id) DESC
            
            # 8. 原生SQL语句
            
                from django.db import connection, connections
                
                cursor = connection.cursor() # connection=default数据
                cursor = connections['db2'].cursor()
                
                cursor.execute("""SELECT * from auth_user where id = %s""", [1])
                
                row = cursor.fetchone()
                row = cursor.fetchall()
                
                
                - extra
                - 原生SQL语句
                - raw
                    result = models.UserInfo.objects.raw('select * from userinfo')
                    [obj(UserInfo),obj,]
                    result = models.UserInfo.objects.raw('select id,1 as name,2 as age,4 as ut_id from usertype')
                    [obj(UserInfo),obj,]
                    
                    v1 = models.UserInfo.objects.raw('SELECT id,title FROM app01_usertype',translations=name_map)
                    
            # 9. 简单的操作
                http://www.cnblogs.com/wupeiqi/articles/6216618.html
            
                
    2. xss攻击
        - 慎用 safe和mark_safe
        - 非要用,一定要过滤关键字
        
    3. CSRF
    
    4. 模板引擎
        - 部分方法
        - 自定义方法
上课笔记0628

1.手动创建第三张关系表:

#多对多关系
class Boy(models.Model):
name = models.CharField(max_length=32)

class Girl(models.Model):
nick = models.CharField(max_length=32)

class Love(models.Model):
b = models.ForeignKey('Boy')
g = models.ForeignKey('Girl')
class Meta:
unique_together = [
('b','g'),#联合唯一索引,女孩和男孩只能约会一次
]
注释掉Love表,然后运行python manage.py makemigrations和python manage.py migrate 会删除第三张表

往三张表插入数据插入数据,

    #多对多
    objs = [
        models.Boy(name='方少伟'),
        models.Boy(name='游勤兵'),
        models.Boy(name='陈涛'),
        models.Boy(name='闫龙'),
        models.Boy(name='吴彦祖'),
    ]
    models.Boy.objects.bulk_create(objs,5)  #批量插入数据,5条提交一次
    objss = [
        models.Girl(nick='张俭会'),
        models.Girl(nick='周明月'),
        models.Girl(nick='小猫'),
        models.Girl(nick='小狗'),
    ]
    models.Girl.objects.bulk_create(objss,5)  #批量插入数据,5条提交一次

    models.Love.objects.create(b_id=1,g_id=3)
    models.Love.objects.create(b_id=1,g_id=4)
    models.Love.objects.create(b_id=2,g_id=1)
    models.Love.objects.create(b_id=2,g_id=2)
from django.shortcuts import render,HttpResponse,redirect
from django.views import View
from app01 import models
from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
from django.db.models import F,Q
from django.db.models import Count,Min,Max,Sum
from django.db import connection,connections

# Create your views here.
def test(request):
    # #多对多
    # objs = [
    #     models.Boy(name='方少伟'),
    #     models.Boy(name='游勤兵'),
    #     models.Boy(name='陈涛'),
    #     models.Boy(name='闫龙'),
    #     models.Boy(name='吴彦祖'),
    # ]
    # models.Boy.objects.bulk_create(objs,5)
    # objss = [
    #     models.Girl(nick='张俭会'),
    #     models.Girl(nick='周明月'),
    #     models.Girl(nick='小猫'),
    #     models.Girl(nick='小狗'),
    # ]
    # models.Girl.objects.bulk_create(objss,5)
    # 
    # models.Love.objects.create(b_id=1,g_id=3)
    # models.Love.objects.create(b_id=1,g_id=4)
    # models.Love.objects.create(b_id=2,g_id=1)
    # models.Love.objects.create(b_id=2,g_id=2)

    # 1.查询和方少伟有染的姑娘:反向操作,连表
    obj = models.Boy.objects.filter(name='方少伟').first()
    love_list = obj.love_set.all()
    print(love_list)#<QuerySet [<Love: Love object>, <Love: Love object>]>
    for row in love_list:
        print(row.g.nick)
    #2第二种方法: 正向操作,连表
    love_list=models.Love.objects.filter(b__name='方少伟')
    for row in love_list:
        print(row.g.nick)

    #3 第三种方法: 正向操作,连表 字典
    love_list=models.Love.objects.filter(b__name='方少伟').values('g__nick')
    print(love_list)#<QuerySet [{'g__nick': '小猫'}, {'g__nick': '小狗'}]>
    for row in love_list:
        print(row['g__nick'])
    return HttpResponse('ok')#小猫 小狗
    # 4 第四种方法: 正向操作,连表  元组
    love_list=models.Love.objects.filter(b__name='方少伟').values_list('g__nick')
    print(love_list)#<QuerySet [('小猫',), ('小狗',)]>
    for row in love_list:
        print(row[0])#小猫 小狗

    # 5 第五种方法: 正向操作,连表  元组
    love_list=models.Love.objects.filter(b__name='方少伟').select_related('g')
    print(love_list)#<QuerySet [<Love: Love object>, <Love: Love object>]>
    for obj in love_list:
        print(obj.g.nick)#小猫 小狗
    return HttpResponse('ok')
多表查询示例

2.自动创建第三张表,如下图所示

#多对多关系
class Boy(models.Model):
    name = models.CharField(max_length=32)
    m = models.ManyToManyField('Girl')

class Girl(models.Model):
    nick = models.CharField(max_length=32)
    # m = models.ManyToManyField('Boy')

#多对多关系
class Boy(models.Model):
    name = models.CharField(max_length=32)
    m = models.ManyToManyField('Girl')

class Girl(models.Model):
    nick = models.CharField(max_length=32)
    # m = models.ManyToManyField('Boy')

class Love(models.Model):
    b = models.ForeignKey('Boy')
    g = models.ForeignKey('Girl')
    class Meta:
        unique_together = [
            ('b','g'),#联合唯一索引,女孩和男孩只能约会一次
        ]
这里会生成四张表,因为models.ManyToManyField字段会生成第三张表,Love是第四张表
这里会生成四张表

#多对多关系
class Boy(models.Model):
    name = models.CharField(max_length=32)
    m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g'))

class Girl(models.Model):
    nick = models.CharField(max_length=32)
    # m = models.ManyToManyField('Boy')

class Love(models.Model):
    b = models.ForeignKey('Boy')
    g = models.ForeignKey('Girl')
    class Meta:
        unique_together = [
            ('b','g'),#联合唯一索引,女孩和男孩只能约会一次
        ]
加了个through和through_fields参数
这里只生成3张表

 CSRF HTML设置成:{{ csrf_token }}打开网页链接http://127.0.0.1:8000/csrf1.html,会生成下图的画面,不会生成input框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

<form method="POST" action="/csrf1.html">

    loAUyDKmKdviy4p2L5fn2A7FbdhllrC7ThgUpJ8K697z97WhLc4PJDyPWBmObuEH
    <input type="text" name="user">
    <input type="submit" name="提交">
</form>

</body>
</html>
查看网页源代码不会有input框

CSRF HTML设置成:{% csrf_token %} 打开网页链接http://127.0.0.1:8000/csrf1.html,会生成下图的画面 

提交之后返回字符串ok

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

<form method="POST" action="/csrf1.html">
    <input type='hidden' name='csrfmiddlewaretoken' value='82DbgE3R8Q7Q8oPXcDYhOhqlJQ6pco9MGVjb7KrfuMJ7JrmccKNJvkRvuebS2rbm' />

    <input type="text" name="user">
    <input type="submit" name="提交">
</form>

</body>
</html>
网页源代码会有input框

 这个图也会看到csrftoken随机字符串

github登录页面输入框也会有这个token随机字符串

加上一个装饰器,会局部禁用,但是前提是全站使用CSRF TOKEN验证

from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def csrf1(request):
    if request.method == "GET":
        return render(request,'csrf1.html')
    else:
        return HttpResponse('ok')

全局禁用CSRF TOKEN验证,局部使用CSRF TOKEN验证,加上这个装饰器@csrf_protect

from django.views.decorators.csrf import csrf_exempt,csrf_protect
# @csrf_exempt
@csrf_protect
def csrf1(request):
    if request.method == "GET":
        return render(request,'csrf1.html')
    else:
        return HttpResponse('ok')

以上是FBV的内容

CBV

Django之CSRF(Ajax请求):

有两种方式:

第一种方式(csrftoken放在data里):

   <form method="POST" action="/csrf1.html">
        {% csrf_token %}
    {#    {{ csrf_token }}#}
        <input id="user" type="text" name="user">
        <input type="submit" name="提交">
        <a onclick="submitForm();">Ajax提交</a>
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    <script>
        function submitForm() {
            var csrf = $('input[name="csrfmiddlewaretoken"]').val();
            var user = $('#user').val();
            $.ajax({
                url:'/csrf1.html',
                type:'POST',
                data:{'user':user,'csrfmiddlewaretoken':csrf},
                success:function(arg) {
                    console.log(arg);
                }
            })
        }
    </script>
第一种方式

'csrfmiddlewaretoken':csrf如果没加这个键值对
这样ajax提交数据 会提示403
浏览器控制台输入如下命令获取csrftoken
document.cookie
"csrftoken=eIFRre9gheSzcS6X0FPxYAFIX1kzUcLjMBlRikxEDauQNVDc0MEZFD6SIpp2KfNT"
获取这样的键值对,根据"="分割
可以通过导入<script src="/static/jquery.cookie.js"></script>
可以自动切片
运行这个命令也可以取值(csrftoken)
$.cookie('csrftoken')
"eIFRre9gheSzcS6X0FPxYAFIX1kzUcLjMBlRikxEDauQNVDc0MEZFD6SIpp2KfNT"

cookie还可以自己设置值
$.cookie('sgadgvhf','999999999999999999999')
"sgadgvhf=999999999999999999999"
document.cookie
"csrftoken=eIFRre9gheSzcS6X0FPxYAFIX1kzUcLjMBlRikxEDauQNVDc0MEZFD6SIpp2KfNT; sgadgvhf=999999999999999999999"

第二种方式:(csrftoken放在请求头里)   

先拿到token:var token = $.cookie('csrftoken'); 再加一个请求头headers:{'X-CSRFToken':token}。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

    <form method="POST" action="/csrf1.html">
        {% csrf_token %}
    {#    {{ csrf_token }}#}
        <input id="user" type="text" name="user">
        <input type="submit" name="提交">
        <a onclick="submitForm();">Ajax提交</a>
    </form>
    <script src="/static/jquery-1.12.4.js"></script>
    <script src="/static/jquery.cookie.js"></script>
    <script>
        function submitForm() {
            var token = $.cookie('csrftoken');
            var user = $('#user').val();
            $.ajax({
                url:'/csrf1.html',
                type:'POST',
                headers:{'X-CSRFToken':token},
                data:{'user':user},
                success:function(arg) {
                    console.log(arg);
                }
            })
        }
    </script>

</body>
</html>
第二种方式

    

          

 

 

原文地址:https://www.cnblogs.com/bingabcd/p/7090702.html