zoukankan      html  css  js  c++  java
  • Django

    1.创建Django

    创建project

    django-admin startproject mysite

    创建app

    python manage.py startapp app01

    其他常用命令

        python manage.py runserver 0.0.0.0
      python manage.py startapp appname
      python manage.py syncdb
      python manage.py makemigrations
      python manage.py migrate

      python manage.py createsuperuser

    2.路由系统

    urls

    views

    Form表单:上传文件、单选、多选、下拉框提交

    前端代码

    <form action="/login/" method="post" enctype="multipart/form-data">
            <p>
                <input type="text" name="user" placeholder="用户名">
            </p>
            <p>
                <input type="password" name="pwd" placeholder="密码">
            </p>
            <p>
                男:<input type="radio" name="gender" value="1">
                女:<input type="radio" name="gender" value="2">
                中:<input type="radio" name="gender" value="3">
            </p>
            <p>
                篮球:<input type="checkbox" name="favor" value="11">
                足球:<input type="checkbox" name="favor" value="22">
                排球:<input type="checkbox" name="favor" value="33">
                气球:<input type="checkbox" name="favor" value="44">
            </p>
            <p>
                <select name="city" multiple>
                    <option value="sh">上海</option>
                    <option value="bj">北京</option>
                    <option value="tj">天津</option>
                </select>
            </p>
            <p>
                <input type="file" name="upload">
            </p>
            <input type="submit" value="提交">
        </form>

     后端代码

    def login(request):
        if request.method == "GET":
            redirect('/index/')
        elif request.method == "POST":
            # u = request.POST.get('user')
            # p = request.POST.get('pwd')
            # if u == 'terry' and p == "123":
            #     return redirect('/index/')
            # g = request.POST.get('gender')
            # print(g)
            # f = request.POST.getlist('favor')
            # print(f)
            # c = request.POST.getlist('city')
            # print(c)
            obj = request.FILES.get('upload')
            import os
            file_path = os.path.join('upload', obj.name)
            f = open(file_path, 'wb')
            for i in obj.chunks():
                f.write(i)
            f.close()
        return render(request, 'login.html')

     Django的CBV和FBV

    FBV: function base view

    CBV: class base view

    CBV示例:

    from django.views import View
    class Home(View):
    
        # 重写父类的dispatch方法
        def dispatch(self, request, *args, **kwargs):
            print('before')  # 执行get或post前可以做一些操作
            # 为了不影响程序效果,将父类的dispatch方法用super继承下来
            result = super(Home, self).dispatch(request, *args, **kwargs)
            print('after')  # 执行完get或post之后可以做一些操作
            return result
    
        def get(self, request):
            print(request.method)
            return render(request, 'home.html')
    
        def post(self, request):
            print(request.method)
            return render(request, 'home.html')
    views代码
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login/', views.login),
        url(r'^index/', views.index),
        url(r'^home/', views.Home.as_view()),
    ]
    Urls
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Title</title>
    </head>
    <body>
        <form action="/home/" method="post">
            <input type="text" name="user">
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    前端代码

     基于正则表达式的动态URL

       

    url(r'^detail-(d+).html', views.detail),  # 会把参数传给args
    url(r'^detail-(?P<nid>d+)-(?P<uid>d+).html', views.detail), # 会把参数传给kwargs

    def detail(request, *args, **kwargs):
    pass

    路由重分发

    mysite  urls.py

    from django.conf.urls import url, include
    
    urlpatterns = [
        url(r'^cmdb/', include("app01.urls")),
        url(r'^monitor/', include("app02.urls")),
    ]

    app01 urls.py

    from app01 import views
    from django.conf.urls import url
    
    
    urlpatterns = [
        url(r'^login/', views.login),
    
    ]

    app02 urls.py

    from app02 import views
    from django.conf.urls import url
    
    
    urlpatterns = [
        url(r'^login/', views.login),
    
    ]

    Django 连 mysql

    settings.py文件

    DATABASES = {
        'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME':'dbname',
        'USER': 'root',
        'PASSWORD': 'xxx',
        'HOST': '',
        'PORT': '',
        }
    }
    
    
    
    # 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替
      
    # 如下设置放置在与project同名的配置的 __init__.py文件中
      
    import pymysql
    pymysql.install_as_MySQLdb() 

    Django ORM 基本增删改查

    增加数据

    models.Userinfo.objects.create(username='root', password='123')

    或者
    obj = models.UserInfo(username='terry',password='123')
    obj.save()
    或者
    dic = {'username': 'root', "password": '666'}
    models.UserInfo.objects.create(**dic)

     删除数据

    models.UserInfo.objects.all().delete()
    models.UserInfo.objects.filter(id=4).delete()
    models.UserInfo.objects.filter(name='alex').delete()

    更新数据

    models.UserInfo.objects.all().update(password='6666')
    models.UserInfo.objects.filter(id=3).update(password='333')

    Django ORM字段

    AutoField(Field)
            - int自增列,必须填入参数 primary_key=True
    
        BigAutoField(AutoField)
            - bigint自增列,必须填入参数 primary_key=True
    
            注:当model中如果没有自增列,则自动会创建一个列名为id的列
            from django.db import models
    
            class UserInfo(models.Model):
                # 自动创建一个列名为id的且为自增的整数列
                username = models.CharField(max_length=32)
    
            class Group(models.Model):
                # 自定义自增列
                nid = models.AutoField(primary_key=True)
                name = models.CharField(max_length=32)
    
        SmallIntegerField(IntegerField):
            - 小整数 -32768 ~ 32767
    
        PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
            - 正小整数 0 ~ 32767
        IntegerField(Field)
            - 整数列(有符号的) -2147483648 ~ 2147483647
    
        PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
            - 正整数 0 ~ 2147483647
    
        BigIntegerField(IntegerField):
            - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
    
        自定义无符号整数字段
    
            class UnsignedIntegerField(models.IntegerField):
                def db_type(self, connection):
                    return 'integer UNSIGNED'
    
            PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
                'AutoField': 'integer AUTO_INCREMENT',
                'BigAutoField': 'bigint AUTO_INCREMENT',
                'BinaryField': 'longblob',
                'BooleanField': 'bool',
                'CharField': 'varchar(%(max_length)s)',
                'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
                'DateField': 'date',
                'DateTimeField': 'datetime',
                'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
                'DurationField': 'bigint',
                'FileField': 'varchar(%(max_length)s)',
                'FilePathField': 'varchar(%(max_length)s)',
                'FloatField': 'double precision',
                'IntegerField': 'integer',
                'BigIntegerField': 'bigint',
                'IPAddressField': 'char(15)',
                'GenericIPAddressField': 'char(39)',
                'NullBooleanField': 'bool',
                'OneToOneField': 'integer',
                'PositiveIntegerField': 'integer UNSIGNED',
                'PositiveSmallIntegerField': 'smallint UNSIGNED',
                'SlugField': 'varchar(%(max_length)s)',
                'SmallIntegerField': 'smallint',
                'TextField': 'longtext',
                'TimeField': 'time',
                'UUIDField': 'char(32)',
    
        BooleanField(Field)
            - 布尔值类型
    
        NullBooleanField(Field):
            - 可以为空的布尔值
    
        CharField(Field)
            - 字符类型
            - 必须提供max_length参数, max_length表示字符长度
    
        TextField(Field)
            - 文本类型
    
        EmailField(CharField):
            - 字符串类型,Django Admin以及ModelForm中提供验证机制
    
        IPAddressField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
    
        GenericIPAddressField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
            - 参数:
                protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
                unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
    
        URLField(CharField)
            - 字符串类型,Django Admin以及ModelForm中提供验证 URL
    
        SlugField(CharField)
            - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
    
        CommaSeparatedIntegerField(CharField)
            - 字符串类型,格式必须为逗号分割的数字
    
        UUIDField(Field)
            - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
    
        FilePathField(Field)
            - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
            - 参数:
                    path,                      文件夹路径
                    match=None,                正则匹配
                    recursive=False,           递归下面的文件夹
                    allow_files=True,          允许文件
                    allow_folders=False,       允许文件夹
    
        FileField(Field)
            - 字符串,路径保存在数据库,文件上传到指定目录
            - 参数:
                upload_to = ""      上传文件的保存路径
                storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
    
        ImageField(FileField)
            - 字符串,路径保存在数据库,文件上传到指定目录
            - 参数:
                upload_to = ""      上传文件的保存路径
                storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
                width_field=None,   上传图片的高度保存的数据库字段名(字符串)
                height_field=None   上传图片的宽度保存的数据库字段名(字符串)
    
        DateTimeField(DateField)
            - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
    
        DateField(DateTimeCheckMixin, Field)
            - 日期格式      YYYY-MM-DD
    
        TimeField(DateTimeCheckMixin, Field)
            - 时间格式      HH:MM[:ss[.uuuuuu]]
    
        DurationField(Field)
            - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
    
        FloatField(Field)
            - 浮点型
    
        DecimalField(Field)
            - 10进制小数
            - 参数:
                max_digits,小数总长度
                decimal_places,小数位长度
    
        BinaryField(Field)
            - 二进制类型
    字段

    Django update time字段使用注意

    auto_add_now字段

    # 不生效
    models.UserInfo.objects.filter(id=1).update(password='6666') 
    
    # 生效
    obj = models.UserInfo.objects.filter(id=3).first()
    obj.caption = 'CEO'
    obj.save()

     choices字段:1.django admin中显示下拉框,2.避免链表查询

    用法:数据库中保存的就是1,2,3数字

    user_type_choices = (
        (1, '超级用户'),
        (2, '普通用户'),
        (3, '访客'),
    )
    
    user_type_id = models.IntegerField(choices=user_type_choices,default=1)

    blank :django admin中是否可以为空

    verbose_name: django admin中显示中文

    editable:django admin是否可以被编辑

    error_messages :django admin显示的错误信息

    help_text: django admin显示的提示

    validators:django form 自定义错误提示

    获取单表数据的三种方式

        v = models.Business.objects.all()  # QuerySet类型,内部元素是对象
        c = models.Business.objects.values('id', 'caption')  # QuerySet类型,内部元素是字典
        v3 = models.Business.objects.values_list('id', 'caption')  #QuerySet类型,内部元素是元祖

    一对多跨表操作获取数据的三种方式 

    v1 = models.Host.objects.all() # 对象
    v2 = models.Host.objects.filter().values('nid', 'hostname', 'port', 'b_id', "b__caption") # 字典
    v3 = models.Host.objects.filter().values_list('nid', 'hostname', 'port', 'b_id', "b__caption") # 元组

     创建多对多关系表

    方式一:自定义表

    class Host(models.Model):
        nid = models.AutoField(primary_key=True)
        hostname = models.CharField(max_length=32, db_index=True)
        ip = models.GenericIPAddressField(protocol='ipv4', db_index=True)
        port = models.IntegerField()
        b = models.ForeignKey(to='Business', to_field='id')
    
    
    class Application(models.Model):
        name = models.CharField(max_length=32)
    
    
    class HostToApp(models.Model):
        hobj = models.ForeignKey(to="Host", to_field='nid')
        aobj = models.ForeignKey(to="Application", to_field="id")

    方式二:自动创建关系表

    class Host(models.Model):
        nid = models.AutoField(primary_key=True)
        hostname = models.CharField(max_length=32, db_index=True)
        ip = models.GenericIPAddressField(protocol='ipv4', db_index=True)
        port = models.IntegerField()
        b = models.ForeignKey(to='Business', to_field='id')
    
    
    class Application(models.Model):
        name = models.CharField(max_length=32)
        r = models.ManyToManyField('Host')

     间接操作第三张表

    obj = Application.objects.get(id=1)
    
    # 增加
    obj.r.add(1)
    obj.r.add(2, 3, 4)
    obj.r.add(*[5, 6, 7])
    
    # 删除
    obj.r.remove(1)
    obj.r.remove(2, 3, 4)
    obj.r.remove(*[5, 6, 7])
    
    # 清空
    obj.r.clear()
    
    # 更新
    obj.r.set([3, 5, 7])  # 只保留 3,5,7,其余全删除

    # 所有相关的主机对象“列表” QuerySet
    obj.r.all()

    Ajax发送数据到后端,后端获取数据代码示例(多对多表操作,添加和修改数据)

      1 <!DOCTYPE html>
      2 <html lang="en">
      3 <head>
      4     <meta charset="UTF-8">
      5     <meta http-equiv="x-ua-compatible" content="IE=edge">
      6     <meta name="viewport" content="width=device-width, initial-scale=1">
      7     <title>Title</title>
      8     <style>
      9         .host {
     10             display: inline-block;
     11             padding: 5px;
     12             margin: 5px;
     13             background: blue;
     14             border: 1px solid red;
     15         }
     16 
     17         .hide {
     18             display: none;
     19         }
     20 
     21         .shade {
     22             position: fixed;
     23             top: 0;
     24             bottom: 0;
     25             left: 0;
     26             right: 0;
     27             background: black;
     28             opacity: 0.6;
     29             z-index: 100;
     30         }
     31 
     32         .add_modal {
     33             position: fixed;
     34             top: 200px;
     35             right: 50%;
     36             height: 300px;
     37             width: 400px;
     38             background: white;
     39             z-index: 101;
     40             margin-right: -200px;
     41         }
     42 
     43         .edit_modal {
     44             position: fixed;
     45             top: 200px;
     46             right: 50%;
     47             height: 300px;
     48             width: 400px;
     49             background: white;
     50             z-index: 101;
     51             margin-right: -200px;
     52         }
     53 
     54         .group {
     55             margin-left: 100px;
     56             margin-top: 100px;
     57         }
     58     </style>
     59 
     60 </head>
     61 <body>
     62 <h1>应用列表</h1>
     63 <input id="add" type="button" value="添加">
     64 <table border="1">
     65     <thead>
     66     <tr>
     67         <th>应用名</th>
     68         <th>应用主机列表</th>
     69         <th>操作</th>
     70     </tr>
     71     </thead>
     72     <tbody>
     73 
     74     {% for app in app_list %}
     75         <tr>
     76             <td aid="{{ app.id }}">{{ app.name }}</td>
     77             <td>{% for host in app.r.all %}
     78                 <span class="host" hid= {{ host.nid }}>{{ host.hostname }}</span>
     79             {% endfor %}
     80             </td>
     81             <td class="edit">编辑</td>
     82         </tr>
     83     {% endfor %}
     84 
     85     </tbody>
     86 </table>
     87 <div class="shade hide"></div>
     88 <div class="add_modal hide">
     89     <div class="group">
     90         <form method="post" action="/app" id="ajax_form">
     91             <div>
     92                 <input type="text" name="appname" placeholder="应用名">
     93             </div>
     94             <div>
     95                 <select name="host" multiple>
     96                     {% for row in host_list %}
     97                         <option value="{{ row.nid }}">{{ row.hostname }}</option>
     98                     {% endfor %}
     99                 </select>
    100             </div>
    101             <input type="submit" value="提交">
    102             <input id="cancel" type="button" value="取消">
    103             <input id="ajax_commit" type="button" value="ajax提交">
    104         </form>
    105     </div>
    106 </div>
    107 <div class="edit_modal hide">
    108     <div class="group">
    109         <form method="post" action="/app" id="edit_ajax_form">
    110             <div>
    111                 <input type="text" name="app_id" class="hide" id="app_id">
    112                 <input type="text" name="appname" id="edit_app_name">
    113             </div>
    114             <div>
    115                 <select name="edit_host" multiple>
    116                     {% for row in host_list %}
    117                         <option value="{{ row.nid }}">{{ row.hostname }}</option>
    118                     {% endfor %}
    119                 </select>
    120             </div>
    121             <input id="edit_cancel" type="button" value="取消">
    122             <input id="edit_ajax_commit" type="button" value="确认编辑">
    123         </form>
    124     </div>
    125 </div>
    126 <script src="/static/jquery-1.12.4.js"></script>
    127 <script>
    128     $(function () {
    129         $('#add').click(function () {
    130             $('.shade,.add_modal').removeClass('hide');
    131         });
    132         $('#cancel').click(function () {
    133             $('.shade,.add_modal').addClass('hide');
    134         });
    135 
    136         $('#ajax_commit').click(function () {
    137             $.ajax({
    138                 url: '/app_ajax',
    139                 type: 'post',
    140                 dataType: 'json',
    141                 data: $('#ajax_form').serialize(), // 获取form中所有的数据
    142                 traditional: true, // 不要将列表转换为json(不要深度序列化参数对象)
    143                 success: function (data) {
    144                     if (data.status) {
    145                         window.location.reload();
    146                     } else {
    147                         alert(data.message);
    148                     }
    149                 }
    150             })
    151         });
    152         $('.edit').click(function () {
    153             $('.shade,.edit_modal').removeClass('hide');
    154             var app_name = $(this).siblings().first().text();
    155             var aid = $(this).siblings().first().attr('aid');
    156             var hid_list = [];
    157             $(this).prev().find('span').each(function () {
    158                 var hid = $(this).attr('hid');
    159                 hid_list.push(hid);
    160             });
    161             $('#edit_app_name').val(app_name);
    162             $('#app_id').val(aid);
    163             $('select[name="edit_host"]').val(hid_list);
    164         });
    165         $('#edit_cancel').click(function () {
    166             $('.shade,.edit_modal').addClass('hide');
    167         });
    168         $('#edit_ajax_commit').click(function () {
    169             $.ajax({
    170                 url: "/edit_app_ajax",
    171                 type: "post",
    172                 dataType: "json",
    173                 data: $('#edit_ajax_form').serialize(),
    174                 traditional: true,
    175                 success: function (data) {
    176                     if (data.status) {
    177                         window.location.reload()
    178                     } else {
    179                         alert(data.message);
    180                     }
    181                 }
    182 
    183             })
    184         })
    185     })
    186 </script>
    187 </body>
    188 </html>
    前端代码
     1 def app_ajax(request):
     2     data = {'status': True, "error": None, "message": None}
     3     if request.method == "GET":
     4         app_list = models.Application.objects.all()
     5         host_list = models.Host.objects.all()
     6         return render(request, 'app.html', {"app_list": app_list, "host_list": host_list})
     7     elif request.method == "POST":
     8         try:
     9             app_name = request.POST.get('appname')
    10             host_list = request.POST.getlist('host')
    11             obj = models.Application.objects.create(name=app_name)
    12             obj.r.add(*host_list)
    13         except Exception as e:
    14             data['status'] = False
    15             data['message'] = e
    16         return HttpResponse(json.dumps(data))
    17 
    18 
    19 def edit_app_ajax(request):
    20     data = {'status': True, "error": None, "message": None}
    21     if request.method == "POST":
    22         try:
    23             aid = request.POST.get('app_id')
    24             app_name = request.POST.get('appname')
    25             host_id_list = request.POST.getlist('edit_host')
    26             obj = models.Application.objects.get(id=int(aid))
    27             obj.name = app_name
    28             obj.save()
    29             obj.r.set(host_id_list)
    30         except Exception as e:
    31             data['status'] = False
    32             data['message'] = e
    33         return HttpResponse(json.dumps(data))
    后端代码
     1 class Host(models.Model):
     2     nid = models.AutoField(primary_key=True)
     3     hostname = models.CharField(max_length=32, db_index=True)
     4     ip = models.GenericIPAddressField(protocol='ipv4', db_index=True)
     5     port = models.IntegerField()
     6     b = models.ForeignKey(to='Business', to_field='id')
     7 
     8 
     9 class Application(models.Model):
    10     name = models.CharField(max_length=32)
    11     r = models.ManyToManyField('Host')
    数据库表结构

    request方法 

    request.GET
    request.POST
    request.FILES
    request.method
    request.path_info
    request.POST.getlist

    print(type(request))
    from django.core.handlers.wsgi import WSGIRequest # request对象

    request.environ # 字典

     自定义simple_tag

    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 文件名

    在顶部load

    	
    {% load xx %}
    

      

    d、使用simple_tag

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

    e、在settings中配置当前app,不然django无法找到自定义的simple_tag

    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01',
    )
    

      

    filter

    a, filter和simple_tag用法相似,

    后端代码

     1 from django import template
     2 from django.utils.safestring import mark_safe
     3 
     4 register = template.Library()
     5 
     6 
     7 @register.simple_tag
     8 def my_simple_tag(v1, v2, v3):
     9     return v1 + v2 + v3
    10 
    11 
    12 @register.filter
    13 def my_filter(v1, v2):
    14     return v1 + v2

    前端代码

    {% extends 'layout.html' %}
    {% load xxoo %}
    
    {% block title %}
        S1
    {% endblock %}
    
    {% block content %}
        S1111111111111111
    
        {% my_simple_tag 1 2 3 %}
    
        {{ "hello"|my_filter:"world" }}
    {% endblock %}

    区别:

    1.simple_tag参数无个数限制,filter最多只能传2个参数

    2.filter可以用在if else语句,simple_tag不支持

    {% if "hello"|my_filter:"world" %}
    {% endif %}

    Cookie 

    1、获取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: 后台控制过期时间

    2、设置Cookie:

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

    由于cookie保存在客户端的电脑上,所以,JavaScript和jquery也可以操作cookie。

    <script src='/static/js/jquery.cookie.js'></script>
    $.cookie("list_pager_num", 30,{ path: '/' });
    

      

    FBV和CBV装饰器 

    FBV:

    def auth(func):
        def inner(request, *args, **kwargs):
            username = request.COOKIES.get('username')
            if not username:
                return redirect('/login/')
            return func(request, *args, **kwargs)
        return inner
    
    def login(request):
        if request.method == "POST":
            u = request.POST.get('username')
            p = request.POST.get('pwd')
            if not user_info.get(u):
                return render(request, 'login.html')
            if user_info[u]['pwd'] == p:
                res = redirect('/index/')
                res.set_cookie("username", u, max_age=10)
                # res.set_signed_cookie("username", u, salt="uuu")  # 加密
                # res.get_signed_cookie("username", salt="uuu")  # 解密
                return res
        return render(request, 'login.html')
    
    
    @auth
    def index(request):
        username = request.COOKIES.get('username')
        return render(request, 'index.html', {'username': username})
    

    CBV:

    1.只对get方法做限制

    from django import views
    from django.utils.decorators import method_decorator
    
    
    class Order(views.View):
        @method_decorator(auth)
        def get(self, request):
            username = request.COOKIES.get('username')
            return render(request, 'index.html', {'username': username})
    
        def post(self, request):
            username = request.COOKIES.get('username')
            return render(request, 'index.html', {'username': username})
    

    2.对所有方法做限制 --dispatch方法:

    from django import views
    from django.utils.decorators import method_decorator
    
    
    class Order(views.View):
        @method_decorator(auth)
        def dispatch(self, request, *args, **kwargs):
            return super(Order, self).dispatch(request, *args, **kwargs)
    
        def get(self, request):
            username = request.COOKIES.get('username')
            return render(request, 'index.html', {'username': username})
    
        def post(self, request):
            username = request.COOKIES.get('username')
            return render(request, 'index.html', {'username': username})
    

      对所有方法做限制,类加装饰器方法:

    @method_decorator(auth, name='dispatch')
    class Order(views.View):
    
        def get(self, request):
            username = request.COOKIES.get('username')
            return render(request, 'index.html', {'username': username})
    
        def post(self, request):
            username = request.COOKIES.get('username')
            return render(request, 'index.html', {'username': username})
    

    Django Session 

    Django中默认支持Session,其内部提供了5种类型的Session供开发者使用:

    • 数据库(默认)
    • 缓存
    • 文件
    • 缓存+数据库
    • 加密cookie

    1、数据库Session

    Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。
     
    a. 配置 settings.py
     
        SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
         
        SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
        SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
        SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
        SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
        SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
        SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
        SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
        SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
     
     
     
    b. 使用
     
        def index(request):
            # 获取、设置、删除Session中数据
            request.session['k1']
            request.session.get('k1',None)
            request.session['k1'] = 123
            request.session.setdefault('k1',123) # 存在则不设置
            del request.session['k1']
     
            # 所有 键、值、键值对
            request.session.keys()
            request.session.values()
            request.session.items()
            request.session.iterkeys()
            request.session.itervalues()
            request.session.iteritems()
     
     
            # 用户session的随机字符串
            request.session.session_key
     
            # 将所有Session失效日期小于当前日期的数据删除
            request.session.clear_expired()
     
            # 检查 用户session的随机字符串 在数据库中是否
            request.session.exists("session_key")
     
            # 删除当前用户的所有Session数据
            request.session.delete("session_key")
     
            request.session.set_expiry(value)
                * 如果value是个整数,session会在些秒数后失效。
                * 如果value是个datatime或timedelta,session就会在这个时间后失效。
                * 如果value是0,用户关闭浏览器session就会失效。
                * 如果value是None,session会依赖全局session失效策略。
    

      2、缓存Session

    a. 配置 settings.py
     
        SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
        SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
     
     
        SESSION_COOKIE_NAME = "sessionid"                        # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
        SESSION_COOKIE_PATH = "/"                                # Session的cookie保存的路径
        SESSION_COOKIE_DOMAIN = None                              # Session的cookie保存的域名
        SESSION_COOKIE_SECURE = False                             # 是否Https传输cookie
        SESSION_COOKIE_HTTPONLY = True                            # 是否Session的cookie只支持http传输
        SESSION_COOKIE_AGE = 1209600                              # Session的cookie失效日期(2周)
        SESSION_EXPIRE_AT_BROWSER_CLOSE = False                   # 是否关闭浏览器使得Session过期
        SESSION_SAVE_EVERY_REQUEST = False                        # 是否每次请求都保存Session,默认修改之后才保存
     
     
     
    b. 使用
     
        同上
    

      3、文件Session

    a. 配置 settings.py
     
        SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
        SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()                                                            # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T
     
     
        SESSION_COOKIE_NAME = "sessionid"                          # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
        SESSION_COOKIE_PATH = "/"                                  # Session的cookie保存的路径
        SESSION_COOKIE_DOMAIN = None                                # Session的cookie保存的域名
        SESSION_COOKIE_SECURE = False                               # 是否Https传输cookie
        SESSION_COOKIE_HTTPONLY = True                              # 是否Session的cookie只支持http传输
        SESSION_COOKIE_AGE = 1209600                                # Session的cookie失效日期(2周)
        SESSION_EXPIRE_AT_BROWSER_CLOSE = False                     # 是否关闭浏览器使得Session过期
        SESSION_SAVE_EVERY_REQUEST = False                          # 是否每次请求都保存Session,默认修改之后才保存
     
    b. 使用
     
        同上
    

      4、缓存+数据库Session

    数据库用于做持久化,缓存用于提高效率
     
    a. 配置 settings.py
     
        SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
     
    b. 使用
     
        同上
    

      5、加密cookie Session

    a. 配置 settings.py
         
        SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
     
    b. 使用
     
        同上
    

      扩展:Session用户验证

    def login(func):
        def wrap(request, *args, **kwargs):
            # 如果未登陆,跳转到指定页面
            if request.path == '/test/':
                return redirect('http://www.baidu.com')
            return func(request, *args, **kwargs)
        return wrap
    

    跨站请求伪造

    一、简介

    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、普通表单

    veiw中设置返回值:
      return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))  
         或者
         return render(request, 'xxx.html', data)
      
    html中设置Token:
      {% csrf_token %}
    

      

    2、Ajax

    对于传统的form,可以通过表单的方式将token再次发送到服务端,而对于ajax的话,使用如下方式。

    view.py

    from django.template.context import RequestContext
    # Create your views here.
      
      
    def test(request):
      
        if request.method == 'POST':
            print request.POST
            return HttpResponse('ok')
        return  render_to_response('app01/test.html',context_instance=RequestContext(request))
    

      text.html

    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        {% csrf_token %}
      
        <input type="button" onclick="Do();"  value="Do it"/>
      
        <script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
        <script src="/static/plugin/jquery/jquery.cookie.js"></script>
        <script type="text/javascript">
            var csrftoken = $.cookie('csrftoken');
      
            function csrfSafeMethod(method) {
                // these HTTP methods do not require CSRF protection
                return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
            }
            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
            });
            function Do(){
      
                $.ajax({
                    url:"/app01/test/",
                    data:{id:1},
                    type:'POST',
                    success:function(data){
                        console.log(data);
                    }
                });
      
            }
        </script>
    </body>
    </html>
    

    缓存

    由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。

    Django中提供了6种缓存方式:

    • 开发调试
    • 内存
    • 文件
    • 数据库
    • Memcache缓存(python-memcached模块)
    • Memcache缓存(pylibmc模块)

    1、配置

    a、开发调试

    # 此为开始调试用,实际内部不做任何操作
        # 配置:
            CACHES = {
                'default': {
                    'BACKEND': 'django.core.cache.backends.dummy.DummyCache',     # 引擎
                    'TIMEOUT': 300,                                               # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
                    'OPTIONS':{
                        'MAX_ENTRIES': 300,                                       # 最大缓存个数(默认300)
                        'CULL_FREQUENCY': 3,                                      # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
                    },
                    'KEY_PREFIX': '',                                             # 缓存key的前缀(默认空)
                    'VERSION': 1,                                                 # 缓存key的版本(默认1)
                    'KEY_FUNCTION' 函数名                                          # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
                }
            }
    
    
        # 自定义key
        def default_key_func(key, key_prefix, version):
            """
            Default function to generate keys.
    
            Constructs the key used by all other methods. By default it prepends
            the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
            function with custom key making behavior.
            """
            return '%s:%s:%s' % (key_prefix, version, key)
    
        def get_key_func(key_func):
            """
            Function to decide which key function to use.
    
            Defaults to ``default_key_func``.
            """
            if key_func is not None:
                if callable(key_func):
                    return key_func
                else:
                    return import_string(key_func)
            return default_key_func
    View Code

    b、内存

     1 # 此缓存将内容保存至内存的变量中
     2     # 配置:
     3         CACHES = {
     4             'default': {
     5                 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
     6                 'LOCATION': 'unique-snowflake',
     7             }
     8         }
     9 
    10     # 注:其他配置同开发调试版本
    View Code

    c、文件

     1 # 此缓存将内容保存至文件
     2     # 配置:
     3 
     4         CACHES = {
     5             'default': {
     6                 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
     7                 'LOCATION': '/var/tmp/django_cache',
     8             }
     9         }
    10     # 注:其他配置同开发调试版本
    View Code

    d、数据库

     1 # 此缓存将内容保存至数据库
     2 
     3     # 配置:
     4         CACHES = {
     5             'default': {
     6                 'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
     7                 'LOCATION': 'my_cache_table', # 数据库表
     8             }
     9         }
    10 
    11     # 注:执行创建表命令 python manage.py createcachetable
    View Code

    e、Memcache缓存(python-memcached模块)

     1 # 此缓存使用python-memcached模块连接memcache
     2 
     3     CACHES = {
     4         'default': {
     5             'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
     6             'LOCATION': '127.0.0.1:11211',
     7         }
     8     }
     9 
    10     CACHES = {
    11         'default': {
    12             'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
    13             'LOCATION': 'unix:/tmp/memcached.sock',
    14         }
    15     }   
    16 
    17     CACHES = {
    18         'default': {
    19             'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
    20             'LOCATION': [
    21                 '172.19.26.240:11211',
    22                 '172.19.26.242:11211',
    23             ]
    24         }
    25     }
    View Code

    f、Memcache缓存(pylibmc模块)

     1 # 此缓存使用pylibmc模块连接memcache
     2     
     3     CACHES = {
     4         'default': {
     5             'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
     6             'LOCATION': '127.0.0.1:11211',
     7         }
     8     }
     9 
    10     CACHES = {
    11         'default': {
    12             'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
    13             'LOCATION': '/tmp/memcached.sock',
    14         }
    15     }   
    16 
    17     CACHES = {
    18         'default': {
    19             'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
    20             'LOCATION': [
    21                 '172.19.26.240:11211',
    22                 '172.19.26.242:11211',
    23             ]
    24         }
    25     }
    View Code

    2、应用

    a. 全站使用

     1 使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存
     2 
     3     MIDDLEWARE = [
     4         'django.middleware.cache.UpdateCacheMiddleware',
     5         # 其他中间件...
     6         'django.middleware.cache.FetchFromCacheMiddleware',
     7     ]
     8 
     9     CACHE_MIDDLEWARE_ALIAS = ""
    10     CACHE_MIDDLEWARE_SECONDS = ""
    11     CACHE_MIDDLEWARE_KEY_PREFIX = ""
    View Code

    b. 单独视图缓存

     1 方式一:
     2         from django.views.decorators.cache import cache_page
     3 
     4         @cache_page(60 * 15)
     5         def my_view(request):
     6             ...
     7 
     8     方式二:
     9         from django.views.decorators.cache import cache_page
    10 
    11         urlpatterns = [
    12             url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
    13         ]
    View Code

    c、局部视图使用

    1 a. 引入TemplateTag
    2 
    3         {% load cache %}
    4 
    5     b. 使用缓存
    6 
    7         {% cache 5000 缓存key %}
    8             缓存内容
    9         {% endcache %}
    View Code

    信号

    Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。

    1、Django内置信号

    Model signals
        pre_init                    # django的modal执行其构造方法前,自动触发
        post_init                   # django的modal执行其构造方法后,自动触发
        pre_save                    # django的modal对象保存前,自动触发
        post_save                   # django的modal对象保存后,自动触发
        pre_delete                  # django的modal对象删除前,自动触发
        post_delete                 # django的modal对象删除后,自动触发
        m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
        class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
    Management signals
        pre_migrate                 # 执行migrate命令前,自动触发
        post_migrate                # 执行migrate命令后,自动触发
    Request/response signals
        request_started             # 请求到来前,自动触发
        request_finished            # 请求结束后,自动触发
        got_request_exception       # 请求异常后,自动触发
    Test signals
        setting_changed             # 使用test测试修改配置文件时,自动触发
        template_rendered           # 使用test测试渲染模板时,自动触发
    Database Wrappers
        connection_created          # 创建数据库连接时,自动触发
    

    对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:

     1 from django.core.signals import request_finished
     2     from django.core.signals import request_started
     3     from django.core.signals import got_request_exception
     4 
     5     from django.db.models.signals import class_prepared
     6     from django.db.models.signals import pre_init, post_init
     7     from django.db.models.signals import pre_save, post_save
     8     from django.db.models.signals import pre_delete, post_delete
     9     from django.db.models.signals import m2m_changed
    10     from django.db.models.signals import pre_migrate, post_migrate
    11 
    12     from django.test.signals import setting_changed
    13     from django.test.signals import template_rendered
    14 
    15     from django.db.backends.signals import connection_created
    16 
    17 
    18     def callback(sender, **kwargs):
    19         print("xxoo_callback")
    20         print(sender,kwargs)
    21 
    22     xxoo.connect(callback)
    23     # xxoo指上述导入的内容
    View Code
    1 from django.core.signals import request_finished
    2 from django.dispatch import receiver
    3 
    4 @receiver(request_finished)
    5 def my_callback(sender, **kwargs):
    6     print("Request finished!")
    View Code

    2、自定义信号

    a. 定义信号

    import django.dispatch
    pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

    b. 注册信号

     

    def callback(sender, **kwargs):
        print("callback")
        print(sender,kwargs)
     
    pizza_done.connect(callback)
    

    c. 触发信号

    from 路径 import pizza_done
     
    pizza_done.send(sender='seven',toppings=123, size=456)
    

    Ajax 跨域请求 jsonp

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title></title>
     6 </head>
     7 <body>
     8 <input type="button" onclick="AjaxRequest()" value="跨域Ajax" />
     9 
    10 
    11 <div id="container"></div>
    12 
    13 <script src="jquery-1.8.2.min.js" type="text/javascript"></script>
    14     <script type="text/javascript">
    15         function AjaxRequest() {
    16             $.ajax({
    17                 url: 'http://www.jxntv.cn/data/jmd-jxtv2.html?callback=list&_=1454376870403',
    18                 type: 'GET',
    19                 dataType: 'jsonp',
    20                 jsonp: 'callback',
    21                 jsonpCallback: 'list',
    22                 success: function (data) {
    23                     $.each(data.data,function(i){
    24                         var item = data.data[i];
    25                         var str = "<p>"+ item.week +"</p>";
    26                         $('#container').append(str);
    27                         $.each(item.list,function(j){
    28                             var temp = "<a href='" + item.list[j].link +"'>" + item.list[j].name +" </a><br/>";
    29                             $('#container').append(temp);
    30                         });
    31                         $('#container').append("<hr/>");
    32                     })
    33 
    34                 }
    35             });
    36         }
    37 </script>
    38 </body>
    39 </html>
    实例:Ajax跨域
  • 相关阅读:
    C++中的ravalue学习笔记
    C++中的抽象类
    C++中的显式类型转换
    C++中的继承和多继承
    C++中的多态
    Yocto学习笔记
    HIDL学习笔记
    hadoop2.5搭建过程
    《Redis设计与实现》学习笔记
    40 数组中只出现一次的数字
  • 原文地址:https://www.cnblogs.com/terrycy/p/6056176.html
Copyright © 2011-2022 走看看