zoukankan      html  css  js  c++  java
  • Django

    一.Django安装与配置:
    刚刚发现一篇不错的Django基础文章:点击---》 简约不简单
    1.windows终端:pip install django

    安装成功后在python配置好环境变量的情况下创建django目录:

    • 命令:
      # 创建Django程序
      django-admin startproject mysite
      # 进入程序目录
      cd mysite
      # 启动socket服务端,等待用户发送请求
      python manage.py runserver 127.0.0.1:8080
     
    2.项目基本目录结构:

    app01:代码处理目录,可以在终端输入 python manage.py startapp app02 继续创建

    CSRF:Django项目同名目录,自取名。其中有DJango配置文件settings,与urls路由映射文件

    static:静态文件存放目录,用于存放CSS代码、Bootstrap等文件。

    templates:网页模版存放目录,一般存放HTML文件。

    utils:可以存放自定制的模块工具。

    db.sqlite3: 数据库文件

    (1).setting文件:
    注册app文件夹,业务代码实际编译文件夹,写入配置中,在创建Django项目时如果同时创建会自动注册。
    1 INSTALLED_APPS = [
    2     'django.contrib.admin',
    3     'django.contrib.auth',
    4     'django.contrib.contenttypes',
    5     'django.contrib.sessions',
    6     'django.contrib.messages',
    7     'django.contrib.staticfiles',
    8     'app01',
    9 ]
     
     
    Csrf,防止跨站请求伪造,在测试阶段可以注释,实际应开启,对应的应在代码中处理,否则将会拒绝网站Post提交。
    templates 网页模版存放路径,Django项目根目录下自动创建。
     
    数据库相关配置:
    Django项目创建时默认为sqlite3,如使用默认的sqlite则不需作任何修改,直接在models模块创建数据表即可。创建完成可以将左边的数据表拖拽到右边Database中使用Pycharm可视化工具。
                                  

    如使用的是Mysql,需要注释默认配置,重新进行相关配置

    首先修改setting文件:

     1 DATABASES = {
     2     'default': {
     3     'ENGINE': 'django.db.backends.mysql',
     4     'NAME':'dbname',
     5     'USER': 'root',
     6     'PASSWORD': 'xxx',
     7     'HOST': '',
     8     'PORT': '3306',
     9     }
    10 }

    随后在同层目录下的__init__.py文件导入对应模块:

     import pymysql 

     pymysql.install_as_MySQLdb() 

    最后便可以在app目录下的models通过代码建表。

    配置static目录。

    1 STATIC_URL = '/static/'
    2 STATICFILES_DIRS = (
    3     os.path.join(BASE_DIR,'static'),
    4 )

    session配置: 

     1 SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # 引擎(默认)
     2 
     3 SESSION_COOKIE_NAME = "sessionid"  # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
     4 SESSION_COOKIE_PATH = "/"  # Session的cookie保存的路径(默认)
     5 SESSION_COOKIE_DOMAIN = None  # Session的cookie保存的域名(默认)
     6 SESSION_COOKIE_SECURE = False  # 是否Https传输cookie(默认)
     7 SESSION_COOKIE_HTTPONLY = True  # 是否Session的cookie只支持http传输(默认)
     8 SESSION_COOKIE_AGE = 2592000  # Session的cookie失效日期(2周)(默认)
     9 SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期(默认)
    10 SESSION_SAVE_EVERY_REQUEST = False  # 是否每次请求都保存Session,默认修改之后才保存(默认)

    二.路由系统:

    存放于urls.py文件。

    网址后面的输入URL,对应着Django里的一个函数。

    (1)一个URL对应一函数:       url(r'^test.html$', views.test),

    (2)基于正则表达式: /add-user/(d+)/  ->  def add_user(request,a1)  name=n1

    url(r'^manage/(?P<name>w*)/(?P<id>d*)', views.manage),
    (3)添加别名:
    url(r'^home', views.home, name='h1'),
    url(r'^index/(d*)', views.index, name='h2'),

    根据名称可以反向生成URL
    1. 在Python代码中
    from django.urls import reverse
    v = reverse('h1',kwargs={'a1':1111})
    print(v)

    2.
    url(r'^login/', views.login,name='m1')
    {% url "m1" %}

    (4)路由分发:

    urls.py
    url(r'^app01/', include('app01.urls')),


    app01.urls.py
    url(r'^index.html$', views.index),

    补充:伪静态。伪静态可以优化网页SEO,在搜索引擎中位置可能更靠前

    url(r'^edit/(w+).html$', views.edit),          以html作为结尾。

    三.模版

    1.当urls的路由系统设置好后,我们便可以在app01的views.py中编写对应函数。

     1 from django.shortcuts import render,HttpResponse,redirect 

    首先导入需要的模块。HttpResponse返回字符串,render返回网页模版,实际经过编译跟HttpResponse本质一样,redirect用于跳转url.

    2.模版语言

    Views代码:

    1 def login(request):
    2      return render(request, 'boys.html', {'user_list': user_list}

    html代码:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Title</title>
     6 </head>
     7 <body>
     8 {#直接显示#}
     9 {{ user_list }}
    10 
    11 {#//模版中的for循环#}
    12 {% for item in user_list %}
    13     <a>{{ item }}</a>
    14 {% endfor %}
    15 
    16 {#模版中if判断#}
    17 {% if user_list == 1 %}
    18 {% else %}
    19 {% endif %}
    20 
    21 </body>
    22 </html>
    View Code

    母板:当一个网站有很多子链接,大多情况下网站下的所有url都有一个统一的基调,比如导航,侧边栏,配色等,这时为防止每个Url都要重写代码,可以将这些公共的模块提取出来制成模版,以后需要用到直接继承即可,节省代码.

      • 母板:{% block title %}{% endblock %}
        子板:{% extends "base.html" %}          #base.html为母板文件名称。
           {% block title %}{% endblock %}

    一般母板中可以建3个block,一个存放CSS即style代码,一个存放html 即body中的代码,一个编写JS即script代码.

    小组件:当页面有一个小块组件需要反复使用,可以用include。

     1 - include
     2             - 导入小组件
     3                 pub.html
     4                     <div>
     5                         <h3>特别漂亮的组件</h3>
     6                         <div class="title">标题:{{ name }}</div>
     7                         <div class="content">内容:{{ name }}</div>
     8                     </div>
     9 
    10 
    11 
    12                 test.html
    13                     <!DOCTYPE html>
    14                     <html lang="en">
    15                     <head>
    16                         <meta charset="UTF-8">
    17                         <title></title>
    18                     </head>
    19                     <body>
    20                         {% include 'pub.html' %}
    21                         {% include 'pub.html' %}
    22                         {% include 'pub.html' %}
    23                     </body>
    24                     </html>

    帮助方法:从后端传来的值后加 |方法名 即可调用由Django封装的python方法。

    {{ item.event_start|date:"Y-m-d H:i:s"}}
    {{ bio|truncatewords:"30" }}
    {{ my_list|first|upper }}
    {{ name|lower }}

    simple_tag:(自定义python方法模版可以使用)

    a、在app中创建templatetags模块

    b、创建任意 .py 文件,如:xx.py

     1 #!/usr/bin/env python
     2 #coding:utf-8
     3 from django import template
     4 from django.utils.safestring import mark_safe
     5    
     6 register = template.Library()
     7    
     8 @register.simple_tag
     9 def my_simple_time(v1,v2,v3):
    10     return  v1 + v2 + v3
    11    
    12 @register.simple_tag
    13 def my_input(id,arg):
    14     result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    15     return mark_safe(result)

    c、在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名 1 {% load xx %} 

    d、使用simple_tag

     1 {% my_simple_time 1 2 3%} 2 {% my_input 'id_username' 'hide'%} 

    e丶在settings中配置当前app,不然django无法找到自定义的simple_tag,已配置忽略。

    1 INSTALLED_APPS = (
    2     'django.contrib.admin',
    3     'django.contrib.auth',
    4     'django.contrib.contenttypes',
    5     'django.contrib.sessions',
    6     'django.contrib.messages',
    7     'django.contrib.staticfiles',
    8     'app01',
    9 )

    - simple_filter
    - 最多两个参数,方式: {{第一个参数|函数名称:"第二个参数"}}
    - 可以做条件判断

    3.模版简单渲染

    可以利用Bootstrap与以及font-awesome等插件对HTML模版进行一个简单的页面渲染,使页面看上去更加美观。详细教程与使用方法可以到官网查看。

    四.models(Django ORM)

    1.基本建表:

     1 from django.db import models #导入django ORM对应模块
     2  
     3  # Create your models here.
     4  class Class1(models.Model):  #继承models模块定制类,即创建表,类名为表明
     5      cid = models.AutoField(primary_key=True)    #创建主键,AutoField为自增(主键可以不写,不写时默认生成一行名称为ID的主键列)
     6     cname = models.CharField(max_length=32)     #创建char类型字符串,最大长度32
     7      
     8  class Teacher(models.Model):
     9      tid = models.AutoField(primary_key=True)
    10      tname = models.CharField(max_length=32)
    11  
    12  class Student(models.Model):
    13      sid = models.AutoField(primary_key=True) 
    14      sname = models.CharField(max_length=32)
    15      Class = models.ForeignKey(Class1)  #创建外键,括号里面填写外键关系的表名 这个类在生成时,Class列会显示为Class_id即自写的列名加_id 
    16  
    17  class Guanxi(models.Model):
    18      teacher = models.ForeignKey(Teacher)
    19      Class = models.ForeignKey(Class1)
    View Code

    当类表定制完毕时,cmd切换到Django项目的根目录,运行命令:(注意将python添加至环境变量)

     python manage.py makemigrations  

     python manage.py migrate 

    此时数据表即完成创建成功,如有报错,注意查看某个字段是否类型错误,检查之前步骤是否有遗漏。

    如果是用的sqlite创建,可以用pycharm自带的可视化以及Django的sqlite结合查看表。(将项目中的sqlite3拖拽到pycharm编辑器右上角点开的Database中)

    2.基于ORM对表进行增删改查:

    本次操作在views模块中,因此首先导入之前创建的表类

    from app01 import models

     1 查:
     2 res = models.UserType.objects.all() #获取表所有数据,得到一个QuerySet[obj,obj,obj],类似一个个对象组成的列表,循环列表取到的为对象,拥有表的字段属性。
     3 for row in res:
     4     print(row.cid,row.cname)
     5 
     6 res = models.UserType.objects.all() .first() #获取表所有数据的第一行,实际为一个Obj对象,可以res.cid,res.cname取值
     7 
     8 res = models.UserType.objects.filter(cid=1) 
     9 res = models.UserInfo.objects.filter(id__gt=1) id大于1
    10 res = models.UserInfo.objects.filter(id__lt=1) id小于1
    11 #filter查询时,括号里面可以添加条件,得到的依然为QuerySet,需要取值依旧需要for 循环 或者后面加.first()方法,当然也可以按索引取值,得到的也是obj对象
    12 
    13 res = models.UserInfo.objects.all().values('id','name') #实际还是QuerySet,括号里面可以限定需要查询的列,不同的是,这里循环出来的不再是对象,而是一个个的字典 QuerySet[{'id':'xx','name':'xx'} ] 取值需按字典key取值。
    14 # 跨表  __
    15     # result = models.UserInfo.objects.all().values('id','name',"ut__title")
    16     # for item in result:
    17     #     print(item['id'],item['name'],item['ut__title'])
    18 
    19 
    20 res = models.UserInfo.objects.all().values_list('id','name') #得到QuerySet[(1,'f'), ] 循环出来的还是一个个的列表,列表索引取值。
    21 
    22 # 跨表  __
    23     # result = models.UserInfo.objects.all().values_list('id','name',"ut__title")
    24     # for item in result:
    25     #     print(item[0],item[1],item[2])
    26 
    27 
    28 
    29 增:
    30 #增加为create(),括号里面填写数据行需要的各个数据即可
    31    models.UserType.objects.create(title='普通用户')
    32 
    33 
    34 
    35 删:
    36 #删除需在查询到数据的基础上,后面加上.delete()方法即可
    37 models.UserInfo.objects.filter(id=1).delete()
    38 
    39 
    40 改:
    41 #对应的,修改也是在查询的基础上,加.update()方法
    42 models.Student.objects.filter(sid=a1).update(sname=name,Class_id=cid)
    43 
    44 #外键操作:以下操作基于2个表已经建立外键关系的基础
    45 ##正向操作:
    46 # UserInfo,ut是FK字段 - 正向操作  PS: 一个用户只有一个用户类型
    47 obj = models.UserInfo.objects.all().first()
    48 print(obj.name,obj.age,obj.ut.title)  
    49 #通过.外键名.对应关系表的字段列名即可拿到UserType表里面的title列值
    50 #同样的如果有多个关系表连表操作时,可以一直.外键无穷无尽的连表取到需要的值
    51 
    52 #反向操作:
    53 # UserType, 表名小写_set.all()  - 反向操作   PS: 一个用户类型下可以有很多用户
    54 obj = models.UserType.objects.all().first() #取到用户类型的其中一个Obj
    55 print('用户类型',obj.id,obj.title)
    56 #通过用户类型查看该类型下有多少个用户
    57  for row in obj.userinfo_set.all():  
    58      print(row.name,row.age)
    59 
    60 
    61 result = models.UserType.objects.all()
    62     for item in result:
    63         print(item.title,item.userinfo_set.filter(name='xx'))
    View Code
    多对多操作
     1 有三个表:
     2 class Boy(models.Model):
     3     name = models.CharField(max_length=32)
     4 
     5 class Girl(models.Model):
     6     nick = models.CharField(max_length=32)
     7 
     8 class Love(models.Model):
     9     b = models.ForeignKey('Boy',null=True)
    10     g = models.ForeignKey('Girl',null=True)
    11     #联合唯一索引
    12     #class Meta:
    13       #  unique_together = [
    14         #    ('b','g'),
    15         #]
    16 
    17 1.通过Boy表中name为条件查找Girl表有关联的nick值:
    18 插数据:
    19 # obj_list = [
    20     #     models.Boy(name='刘德华'),
    21     #     models.Boy(name='张学友'),
    22     #     models.Boy(name='郭富城'),
    23     #     models.Boy(name='黎明'),
    24     # ]
    25     # objs = [
    26     #     models.Girl(nick='陈慧琳'),
    27     #     models.Girl(nick='容祖儿'),
    28     #     models.Girl(nick='郑秀文'),
    29     #     models.Girl(nick='蒙嘉慧'),
    30     #     ]
    31     # models.Boy.objects.bulk_create(obj_list,5)
    32     # models.Girl.objects.bulk_create(objs,5)
    33 建立关系
    34     # models.Love.objects.create(b_id=1,g_id=1)
    35     # models.Love.objects.create(b_id=1,g_id=4)
    36     # models.Love.objects.create(b_id=2,g_id=2)
    37     # models.Love.objects.create(b_id=2,g_id=3)
    38     # models.Love.objects.create(b_id=2,g_id=4)
    39 多对多的关系查询:
    40     # lo_list = models.Love.objects.filter(b__name='刘德华').values('b__name','g__nick')
    41     # for i in lo_list:
    42     #     print(i['b__name'],i['g__nick'])
    43     #
    44     # lov_list = models.Love.objects.filter(b__name='张学友').select_related('b','g')
    45     # for row in lov_list:
    46     #     print(row.b.name,row.g.nick)
    47 
    48 二。两个表的关系也可以不再建关系表Love,通过Django内置ORM的功能同样可以建立表之间的关系,查找时通过间接查找。
    49 class Boy(models.Model):
    50     name = models.CharField(max_length=32)
    51     m = models.ManyToManyField('Girl')
    52 
    53 class Girl(models.Model):
    54     nick = models.CharField(max_length=32)
    55 
    56 如此,同样可以建立关系,只不过增删改查相应也有变化。
    57 
    58 obj = models.Boy.objects.filter(name='刘德华').first()  #取到筛选出的Boy对象:
    59     #
    60     obj.m.add(1)
    61     obj.m.add(*[2,3,])
    62 
    63     # 删:
    64     obj.m.remove(1,)
    65     obj.m.remove(*[2,])
    66 
    67     #
    68     obj.m.set([1,2,])  #实为重置,将之前的全部删除重新建立关系
    69 
    70     #
    71     q = obj.m.all()  #q得到对应关系的Girl对象
    View Code
     1 class UserInfo(models.Model):
     2         nid = models.AutoField(primary_key=True)
     3         username = models.CharField(max_length=32)
     4         class Meta:
     5             # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
     6             db_table = "table_name"
     7 
     8             # 联合索引
     9             index_together = [
    10                 ("pub_date", "deadline"),
    11             ]
    12 
    13             # 联合唯一索引
    14             unique_together = (("driver", "restaurant"),)
    15 
    16             # admin中显示的表名称
    17             verbose_name
    18 
    19             # verbose_name加s
    20             verbose_name_plural
    元信息
     1 #表结构
     2 class UserInfo(models.Model):
     3     nickname = models.CharField(max_length=32)
     4     username = models.CharField(max_length=32)
     5     pwd = models.CharField(max_length=32)
     6     sex_choices = (        
     7         (1,''),
     8         (2,''),
     9     )
    10     sex = models.IntegerField(choices=sex_choices)  #枚举
    11 
    12 class U2U(models.Model):
    13     g = models.ForeignKey('UserInfo',related_name='boys')
    14     b = models.ForeignKey('UserInfo',related_name='girls')
    15    
    16 #   FK自关联一个表时,表就无法自己做约束,只能由自己保证在插入数据时确保插入正确。
    17 
    18 #代码查询:
    19 from django.shortcuts import render,HttpResponse
    20 from app01 import models
    21 
    22 # Create your views here.
    23 def test(request):
    24     obj = models.UserInfo.objects.filter(id=1,sex=1).first() #首先查询到一个男生对象
    25     l = obj.girls.all()    #通过男生对象,再根据设置的别名反向查找到对应的所有女生,此时l是一个U2U的queryset集合。
    26     for i in l:       #循环每个u2u queryset对象,打印由U2U obj对象通过外键g 正向查找,找到与此男生有关的女生对象。
    27         print(obj.nickname,'--------',i.g.nickname) 
    28 
    29     return HttpResponse('ok!')
    30             
    FK自关联及别名应用

    进阶操作:

     1 # 获取个数
     2         #
     3         # models.Tb1.objects.filter(name='seven').count()
     4 
     5         # 大于,小于
     6         #
     7         # models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
     8         # models.Tb1.objects.filter(id__gte=1)              # 获取id大于等于1的值
     9         # models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
    10         # models.Tb1.objects.filter(id__lte=10)             # 获取id小于10的值
    11         # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
    12 
    13         # in
    14         #
    15         # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
    16         # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
    17 
    18         # isnull
    19         # Entry.objects.filter(pub_date__isnull=True)
    20 
    21         # contains
    22         #
    23         # models.Tb1.objects.filter(name__contains="ven")
    24         # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
    25         # models.Tb1.objects.exclude(name__icontains="ven")
    26 
    27         # range
    28         #
    29         # models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and
    30 
    31         # 其他类似
    32         #
    33         # startswith,istartswith, endswith, iendswith,
    34 
    35         # order by
    36         #
    37         # models.Tb1.objects.filter(name='seven').order_by('id')    # asc
    38         # models.Tb1.objects.filter(name='seven').order_by('-id')   # desc
    39 
    40         # group by
    41         #
    42         # from django.db.models import Count, Min, Max, Sum
    43         # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
    44         # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
    45 
    46         # limit 、offset
    47         #
    48         # models.Tb1.objects.all()[10:20]
    49 
    50         # regex正则匹配,iregex 不区分大小写
    51         #
    52         # Entry.objects.get(title__regex=r'^(An?|The) +')
    53         # Entry.objects.get(title__iregex=r'^(an?|the) +')
    54 
    55         # date
    56         #
    57         # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
    58         # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))
    59 
    60         # year
    61         #
    62         # Entry.objects.filter(pub_date__year=2005)
    63         # Entry.objects.filter(pub_date__year__gte=2005)
    64 
    65         # month
    66         #
    67         # Entry.objects.filter(pub_date__month=12)
    68         # Entry.objects.filter(pub_date__month__gte=6)
    69 
    70         # day
    71         #
    72         # Entry.objects.filter(pub_date__day=3)
    73         # Entry.objects.filter(pub_date__day__gte=3)
    74 
    75         # week_day
    76         #
    77         # Entry.objects.filter(pub_date__week_day=2)
    78         # Entry.objects.filter(pub_date__week_day__gte=2)
    79 
    80         # hour
    81         #
    82         # Event.objects.filter(timestamp__hour=23)
    83         # Event.objects.filter(time__hour=5)
    84         # Event.objects.filter(timestamp__hour__gte=12)
    85 
    86         # minute
    87         #
    88         # Event.objects.filter(timestamp__minute=29)
    89         # Event.objects.filter(time__minute=46)
    90         # Event.objects.filter(timestamp__minute__gte=29)
    91 
    92         # second
    93         #
    94         # Event.objects.filter(timestamp__second=31)
    95         # Event.objects.filter(time__second=2)
    96         # Event.objects.filter(timestamp__second__gte=31)
    View Code
     1 # extra
     2     #
     3     # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
     4     #    Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
     5     #    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
     6     #    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
     7     #    Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])
     8 
     9     # F
    10     #
    11     # from django.db.models import F
    12     # models.Tb1.objects.update(num=F('num')+1)
    13 
    14 
    15     # Q
    16     #
    17     # 方式一:
    18     # Q(nid__gt=10)
    19     # Q(nid=8) | Q(nid__gt=10)
    20     # Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
    21     # 方式二:
    22     # con = Q()
    23     # q1 = Q()
    24     # q1.connector = 'OR'
    25     # q1.children.append(('id', 1))
    26     # q1.children.append(('id', 10))
    27     # q1.children.append(('id', 9))
    28     # q2 = Q()
    29     # q2.connector = 'OR'
    30     # q2.children.append(('c1', 1))
    31     # q2.children.append(('c1', 10))
    32     # q2.children.append(('c1', 9))
    33     # con.add(q1, 'AND')
    34     # con.add(q2, 'AND')
    35     #
    36     # models.Tb1.objects.filter(con)
    37 
    38 
    39     # 执行原生SQL
    40     #
    41     # from django.db import connection, connections
    42     # cursor = connection.cursor()  # cursor = connections['default'].cursor()
    43     # cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    44     # row = cursor.fetchone()
    45 
    46 其他操作
    其它进阶

    五:网页登录验证

    1.CSRF:跨站请求伪造

    POST提交时,需要用户携带随机字符

     1 html中:
     2 - Form
     3 {% csrf_token %}
     4 
     5 
     6 - Ajax
     7 - data
     8 - cookie中获取,添加到请求头,需要使用 jquery.cookie.js
     9 
    10 var token = $.cookie('csrftoken');
    11 $.ajax({
    12     url: '/login.html',
    13     type: 'POST',
    14     headers:{'X-CSRFToken': token},

    全局开启:

    中间件 django.middleware.csrf.CsrfViewMiddleware

    局部:导入模块:from django.views.decorators.csrf import csrf_exempt,csrf_protect

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

    2.XSS攻击:用户评论在HTML中解析为js代码造成网站攻击。如 

    <script> alert(SB!) </script>

    Django中自动防止此类攻击,只要不再模版中使用safe 如 {{ user|safe }} 或者后台Python中 

    1 from django.utils.safestring import mark_safe 
    2 def login(request):    
    3     result = ‘<strong>%s</strong>%s’ % (esc(first), esc(other)) 
    4      return mark_safe(result) 

    如生产环境中有硬性需要,可以对接收的数据做一个过滤,如用户发来的有类似JS代码则不处理。

    3. Cookie:在浏览器上保存的键值对

    (1)设置cookie:

    1 res = HttpResponse(...) 或 rep = render(request, ...)
    2 res.set_cookie(key,value,...)
    3 res.set_signed_cookie(key,value,salt='加密盐',...)
    4 return res
    1  参数:
    2         key,              键
    3         value='',         值
    4         max_age=None,     超时时间
    5         expires=None,     超时时间(IE requires expires, so set it if hasn't been already.)
    6         path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
    7         domain=None,      Cookie生效的域名
    8         secure=False,     https传输
    9         httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

    (2)获取cookie

    1 request.COOKIES['key']
    2 request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    3     参数:
    4         default: 默认值
    5            salt: 加密盐
    6         max_age: 后台控制过期时间

    4.Session

    保存在服务端的数据(本质是键值对)

     1 #配置写在settings中:
     2 1.基于数据库:
     3 SESSION_ENGINE = 'django.contrib.sessions.backends.db'  # 引擎(默认)
     4 
     5 SESSION_COOKIE_NAME = "sessionid"  # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
     6 SESSION_COOKIE_PATH = "/"  # Session的cookie保存的路径(默认)
     7 SESSION_COOKIE_DOMAIN = None  # Session的cookie保存的域名(默认)
     8 SESSION_COOKIE_SECURE = False  # 是否Https传输cookie(默认)
     9 SESSION_COOKIE_HTTPONLY = True  # 是否Session的cookie只支持http传输(默认)
    10 SESSION_COOKIE_AGE = 2592000  # Session的cookie失效日期(2周)(默认)
    11 SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期(默认)
    12 SESSION_SAVE_EVERY_REQUEST = False  # 是否每次请求都保存Session,默认修改之后才保存(默认)
    session默认配置
    1
     1  #获取session:    
     2  def index(request):
     3          u_session = request.session.get('user')
     4          if not u_session:
     5              return redirect('/login.html')  #如未获取重定向登录页面
     6          return render(request,'index.html')
     7 
     8 #设置session
     9  def login(request):
    10   
    11     request.session['key'] = value
     1 def index(request):
     2         # 获取、设置、删除Session中数据
     3         request.session['k1']
     4         request.session.get('k1',None)
     5         request.session['k1'] = 123
     6         request.session.setdefault('k1',123) # 存在则不设置
     7         del request.session['k1']
     8  
     9         # 所有 键、值、键值对
    10         request.session.keys()
    11         request.session.values()
    12         request.session.items()
    13         request.session.iterkeys()
    14         request.session.itervalues()
    15         request.session.iteritems()
    16  
    17  
    18         # 用户session的随机字符串
    19         request.session.session_key
    20  
    21         # 将所有Session失效日期小于当前日期的数据删除
    22         request.session.clear_expired()
    23  
    24         # 检查 用户session的随机字符串 在数据库中是否
    25         request.session.exists("session_key")
    26  
    27         # 删除当前用户的所有Session数据
    28         request.session.delete("session_key")
    29  
    30         request.session.set_expiry(value)
    31             * 如果value是个整数,session会在些秒数后失效。
    32             * 如果value是个datatime或timedelta,session就会在这个时间后失效。
    33             * 如果value是0,用户关闭浏览器session就会失效。
    34             * 如果value是None,session会依赖全局session失效策略。
    其它操作

    六.FBV&CBV

    1.URLS路由配置

    url(r'^login.html$', views.Login.as_view()),
    1 from django.views import View
    2 
    3 class Login(View):
    4     def get(self,request):      #当get访问一个函数
    5         return render(request,'login.html')
    6     
    7     def post(self,request):    #post一个函数
    8         return HttpResponse(‘ok!’)        

    。。。。。。

    七.中间件:

    1 MIDDLEWARE = [
    2     'django.middleware.security.SecurityMiddleware',
    3     'django.contrib.sessions.middleware.SessionMiddleware',
    4     'django.middleware.common.CommonMiddleware',
    5     'django.middleware.csrf.CsrfViewMiddleware',
    6     'django.contrib.auth.middleware.AuthenticationMiddleware',
    7     'django.contrib.messages.middleware.MessageMiddleware',
    8     'django.middleware.clickjacking.XFrameOptionsMiddleware',
    9 ]

    当用户访问时,需要经过这些中间件到达服务端,服务端处理完试图函数,需要再次跨过这些中间件将数据发送到客户端。相当于每次访问来回都需要执行这些中间件的方法一方法二。










     
     
  • 相关阅读:
    uva 10306
    系统学习Linux的11点建议
    SharePoint 2013 讨论板列表"Connect to Outlook" 不可用解决方案
    Java可视化编程,基于布局管理器的UI设计
    【JavaScript脚本编程技术详解-----(一)】
    一个百度程序员的创业故事
    HDU 4729 An Easy Problem for Elfness (主席树,树上第K大)
    Android SQLite Database Tutorial
    最优化方法在图像处理中的应用【4】
    [置顶] 编辑框Editext光标最后显示
  • 原文地址:https://www.cnblogs.com/mitsui/p/7105827.html
Copyright © 2011-2022 走看看