首页 > 代码库 > 框架Django番外篇

框架Django番外篇

技术分享

 

###下载和创建Django的Project

a.1在cmd中,输入下载指令

pip3 install django

 

2.在cmd下创建的命令

技术分享
# 创建Django程序
           django-admin startproject mysite
           # 进入程序目录
           cd mysite
           # 启动socket服务端,等待用户发送请求
           python manage.py runserver 127.0.0.1:8080
 
   python manage.py runserver  #默认 8000
View Code

 

b.1在Pycharm 创建以及配置(#额外配置:CSRF)

技术分享
1- 模板路径
                    template目录
                    
                    TEMPLATES = [
                        {
                            BACKEND: django.template.backends.django.DjangoTemplates,
                            DIRS: [os.path.join(BASE_DIR, template)],    #!!!
                            APP_DIRS: True,
                            OPTIONS: {
                                context_processors: [
                                    django.template.context_processors.debug,
                                    django.template.context_processors.request,
                                    django.contrib.auth.context_processors.auth,
                                    django.contrib.messages.context_processors.messages,
                                ],
                            },
                        },
                    ]
                - 静态文件路径
                    static目录
                    
                    STATIC_URL = /static/
                    
                    STATICFILES_DIRS = (                #! ! ! 
                        os.path.join(BASE_DIR,static),
                    )




2-额外配置  ---------- (使用 中间件时,不再 配置)

MIDDLEWARE = [
                django.middleware.security.SecurityMiddleware,
                django.contrib.sessions.middleware.SessionMiddleware,
                django.middleware.common.CommonMiddleware,
                #‘django.middleware.csrf.CsrfViewMiddleware‘,  !!!!!!
                django.contrib.auth.middleware.AuthenticationMiddleware,
                django.contrib.messages.middleware.MessageMiddleware,
                django.middleware.clickjacking.XFrameOptionsMiddleware,
            ]
                
View Code
技术分享
a. 基本应用
            form表单中添加
            {% csrf_token %}
        
        b. 全站禁用
            # ‘django.middleware.csrf.CsrfViewMiddleware‘,
        
        c. 局部禁用
            django.middleware.csrf.CsrfViewMiddleware,
            
            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)
        d. 局部使用
            # ‘django.middleware.csrf.CsrfViewMiddleware‘,
            
            from django.views.decorators.csrf import csrf_exempt,csrf_protect

            @csrf_protect
            def csrf1(request):

                if request.method == GET:
                    return render(request,csrf1.html)
                else:
                    return HttpResponse(ok)
        
        c. 特殊CBV
                from django.views import View
                from django.utils.decorators import method_decorator
                
                @method_decorator(csrf_protect,name=dispatch)
                class Foo(View):
                    
                    def get(self,request):
                        pass

                    def post(self,request):
                        pass
        
        PS:CBV中添加装饰器
            def wrapper(func):
                def inner(*args,**kwargs):
                    return func(*args,**kwargs)
                return inner
            # 1. 指定方法上添加装饰器

                # class Foo(View):
                #
                #     @method_decorator(wrapper)
                #     def get(self,request):
                #         pass
                #
                #     def post(self,request):
                #         pass
            # 2. 在类上添加
                #     @method_decorator(wrapper,name=‘dispatch‘)
                #     class Foo(View):
                #
                #         def get(self,request):
                #             pass
                #
                #         def post(self,request):
                #             pass
            
        
        Ajax提交数据时候,携带CSRF:
            a. 放置在data中携带
            
                <form method="POST" action="/csrf1.html">
                    {% csrf_token %}
                    <input id="user" type="text" name="user" />
                    <input type="submit" value=http://www.mamicode.com/"提交"/>
                    <a onclick="submitForm();">Ajax提交</a>
                </form>
                <script src=http://www.mamicode.com/"/static/jquery-1.12.4.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>
                
            b. 放在请求头中
            
                    <form method="POST" action="/csrf1.html">
                        {% csrf_token %}
                        <input id="user" type="text" name="user" />
                        <input type="submit" value=http://www.mamicode.com/"提交"/>
                        <a onclick="submitForm();">Ajax提交</a>
                    </form>
                    <script src=http://www.mamicode.com/"/static/jquery-1.12.4.js"></script>
                    <script src=http://www.mamicode.com/"/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>
            
CSRF

 

 

 

I.请求

如:

技术分享
IP+端口号+name

http://127.0.0.1:8000/login

http://127.0.0.1:8000/login.html   -----(.html 是伪静态)
View Code

 

 


 

 

 

 

II.Django

2.中间件

django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件。

代码:

技术分享
MIDDLEWARE = [
    django.middleware.security.SecurityMiddleware,
    django.contrib.sessions.middleware.SessionMiddleware,
    django.middleware.common.CommonMiddleware,
    django.middleware.csrf.CsrfViewMiddleware,
    django.contrib.auth.middleware.AuthenticationMiddleware,
    django.contrib.messages.middleware.MessageMiddleware,
    django.middleware.clickjacking.XFrameOptionsMiddleware,
]
View Code

 

 2.1

 

 

技术分享

 

 

技术分享

#可用于:1.黑名单  2.免登陆

 

2.2.自定义中间件

代码:

1.注册中间件(settings.py)

技术分享
MIDDLEWARE = [
    django.middleware.security.SecurityMiddleware,
    django.contrib.sessions.middleware.SessionMiddleware,
    django.middleware.common.CommonMiddleware,
    django.middleware.csrf.CsrfViewMiddleware,
    django.contrib.auth.middleware.AuthenticationMiddleware,
    django.contrib.messages.middleware.MessageMiddleware,
    django.middleware.clickjacking.XFrameOptionsMiddleware,
    
    
    m1.Middle1,
    m1.Middle2,
]
View Code

 

2.创建中间件(m1.py:)

技术分享
from django.utils.deprecation import MiddlewareMixin

from django.shortcuts import HttpResponse



#中间件 一
class Middle1(MiddlewareMixin):
    def process_request(self, request):
        print(m1.process_request)
        # return HttpResponse(‘不要在往下周了‘)

    def process_response(self, request, response):
        print(m1.process_response)
        return response


#中间件 二
class Middle2(MiddlewareMixin):
    def process_request(self, request):
        print(m2.process_request)
        # return HttpResponse(‘不要在往下周了‘)

    def process_response(self, request, response):
        print(m2.process_response)
        return response
View Code

 

 

 执行结果:

技术分享

 

 

 3.路由关系的匹配

3.1.路由

3.1.1单一路由

技术分享
rom django.conf.urls import url
from django.contrib import admin

from app01.views import love
from app01.views import account

urlpatterns = [
    
    
    url(r^admin/, admin.site.urls),

    url(r^login.html$,account.login),
    url(r^logout.html$,account.logout),

    url(r^index.html$,love.index),
    url(r^others.html$,love.others),

]
View Code

 

3.1.2 基于正则的路由

url(r‘^index/(\d*)‘, views.index),

url(r‘^manage/(?P<name>\w*)/(?P<id>\d*)‘, views.manage),

 3.1.3 添加额外的参数

url(r‘^manage/(?P<name>\w*)‘, views.manage,{‘id‘:333}),

 3.1.4为路由映射设置名称

url(r‘^home‘, views.home, name=‘h1‘),

url(r‘^index/(\d*)‘, views.index, name=‘h2‘),

 

 3.1.5路由分发

技术分享
urls.py
                url(r^app01/, include(app01.urls)),
            
            app01.urls.py
                url(r^index.html$, views.index),
View Code

 

 

3.2 url(r‘^admin/‘, admin.site.urls)的 admin

  django amdin是django提供的一个后台管理页面,改管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后,就可以对数据进行增删改查

3.2.1创建一个用户

技术分享

 

 3.2.2向admin中增加一栏 UserInfo

技术分享

 

 3.2.3效果

技术分享

 

4.函数(模版和数据渲染)

4.1模版

4.1.1模版的执行

模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。

 

4.1.2模版语言

技术分享
?{{ item }}
?{% for item in item_list %}  <a>{{ item }}</a>  {% endfor %}
  forloop.counter
  forloop.first
  forloop.last 
?{% if ordered_warranty %}  {% else %} {% endif %}
?母板:{% block title %}{% endblock %}
子板:{% extends "base.html" %}
   {% block title %}{% endblock %}
?帮助方法:
{{ item.event_start|date:"Y-m-d H:i:s"}}
{{ bio|truncatewords:"30" }}
{{ my_list|first|upper }}
{{ name|lower }}
View Code

 

4.2自定义simple_filter ,simple_tag  (模板自定义函数)

a、在app中创建templatetags模块

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

技术分享
from django import template

register = template.Library()    #register  一词固定写法

@register.filter
def my_upper(value):
    return value.upper()


@register.filter
def my_u(value,arg):
    return value+arg


@register.filter
def my_bool(value):
    return False


@register.simple_tag
def my_lower(value,a1,a2,a3):

    return value + a1 + a2 + a3
View Code

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

技术分享
{% load xx %}
{# 导入此句 #}


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>打印字典所有的key</h1>

    {{ name|my_upper }}
    {{ name|my_u:666 }}



    <h2>filter</h2>
        {{ name|my_u:"666" }}

        {% if name|my_bool %}
            <h3>真</h3>
        {% else %}
            <h3>假</h3>
        {% endif %}
    <h2>tag</h2>
        {% my_lower "ALEX" "x" "SB" "V" %}



</body>
</html>
View Code

d、在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,

)
View Code

 

4.3母版

4.3.1layout.html

技术分享
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <link rel="stylesheet" href=http://www.mamicode.com/"/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" />
    <link rel="stylesheet" href=http://www.mamicode.com/"/static/plugins/font-awesome-4.7.0/css/font-awesome.css" />
    <link rel="stylesheet" href=http://www.mamicode.com/"/static/css/commons.css" />
    {% block css %}{% endblock %}
</head>
<body>


    <div class="pg-header">
        <div class="logo left">老男孩后台管理</div>
        <div class="avatar right" style="position: relative">
            <img style="width: 40px;height: 40px;" src=http://www.mamicode.com/"/static/images/1.jpg">
            <div class="user-info">
                <a>个人资料</a>
                <a>注销</a>
            </div>
        </div>
        <div class="rmenus right">
            <a><i class="fa fa-commenting-o" aria-hidden="true"></i> 消息</a>
            <a><i class="fa fa-envelope-o" aria-hidden="true"></i> 邮件</a>
        </div>
    </div>
    <div class="pg-body">
        <div class="menus">
            <a> <i class="fa fa-futbol-o" aria-hidden="true"></i> 班级管理</a>
            <a>学生管</a>
            <a>老师管理</a>
        </div>
        <div class="content">
            <ol class="breadcrumb">
              <li><a href=http://www.mamicode.com/"#">首页</a></li>
              <li><a href=http://www.mamicode.com/"#">班级管理</a></li>
              <li class="active">添加班级</li>
            </ol>
            {% block xx  %}{% endblock %}

        </div>
    </div>
    {% block js %}{% endblock %}




</body>
</html>
View Code

4.3.2index,html

技术分享
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <ul>
        {% for row in posts.object_list %}
            <li>{{ row.name }}</li>
        {% endfor %}
    </ul>

    <div>
        {% if posts.has_previous %}
            <a href=http://www.mamicode.com/"/index.html?page={{ posts.previous_page_number }}">上一页</a>
        {% endif %}


        {% if posts.has_next %}
            <a href=http://www.mamicode.com/"/index.html?page={{ posts.next_page_number }}">下一页</a>
        {% endif %}
    </div>



</body>
</html>
View Code

#笔记内容

技术分享
layout.html
            {% block x1 %}{%endblock%}
            <h1>ff</h1>
            {% block x2 %}{%endblock%}
            <h1>2</h1>...
            {% block x3 %}{%endblock%}
        index.html
            {%extends layout%}
            
            {% block x1 %}dfssssssdfsd{%endblock%}
            
            {% block x2 %}dfsdfsd{%endblock%}
            
            {% block x3 %}fff{%endblock%}
View Code

 

 4.4include

a.pub.html(只有一个 div)

技术分享
<div>
    <h3>特别漂亮的组件</h3>
    <div>
        <div class="title">标题:</div>
        <div class="content">内容:</div>

    </div>
</div>
View Code

b.在另一个.html中,引入使用

技术分享
% load xx %}
{# 导入此句 #}


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


    {% include pub.html %}
    {% include pub.html %}
    {% include pub.html %}
     {% include pub.html %}
    




{#    <h1>打印字典所有的key</h1>#}
{##}
{#    {{ name|my_upper }}#}
{#    {{ name|my_u:‘666‘ }}#}
{##}
{##}
{##}
{#    <h2>filter</h2>#}
{#        {{ name|my_u:"666" }}#}
{##}
{#        {% if name|my_bool %}#}
{#            <h3>真</h3>#}
{#        {% else %}#}
{#            <h3>假</h3>#}
{#        {% endif %}#}
{#    <h2>tag</h2>#}
{#        {% my_lower "ALEX" "x" "SB" "V" %}#}



</body>
</html>
View Code

技术分享

#笔记内容

技术分享
1. 模板
        - 基本使用
        - 母版
            - 页面继承
        - include
            - 导入小组件
                pub.html
                    <div>
                        <h3>特别漂亮的组件</h3>
                        <div class="title">标题:{{ name }}</div>
                        <div class="content">内容:{{ name }}</div>
                    </div>
                test.html
                    <!DOCTYPE html>
                    <html lang="en">
                    <head>
                        <meta charset="UTF-8">
                        <title></title>
                    </head>
                    <body>
                        {% include pub.html %}
                        {% include pub.html %}
                        {% include pub.html %}
                    </body>
                    </html>
        - 函数-> 自动执行
        - 模板自定义函数:
            - simple_filter
                - 最多两个参数,方式: {{第一个参数|函数名称:"第二个参数"}}
                - 可以做条件判断
            - simple_tag
                - 无限制: {% 函数名 参数 参数%}
View Code

 

 

4.5Cookie

保存在客户端浏览器的键值对

4.5.1获取Cookie

技术分享
request.COOKIES[key]
request.get_signed_cookie(key, default=RAISE_ERROR, salt=‘‘, max_age=None)
    参数:
        default: 默认值
           salt: 加密盐
        max_age: 后台控制过期时间
View Code

4.5.2设置Cookie:

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

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

技术分享
<script src=http://www.mamicode.com//static/js/jquery.cookie.js></script>
$.cookie("list_pager_num", 30,{ path: / });
View Code

 

4.6.Session

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

应用:依赖cookie
作用:保持会话(Web网站)
好处:敏感信息不会直接给客户端

Session五种类型:

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


       

4.6.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失效策略。
View Code

 

4.6.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. 使用
 
    同上
View Code

 

4.6.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. 使用
 
    同上
View Code

 

4.6.4缓存+数据库Session

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

 

4.6.5加密cookie Session

技术分享
a. 配置 settings.py
     
    SESSION_ENGINE = django.contrib.sessions.backends.signed_cookies   # 引擎
 
b. 使用
 
    同上
View Code

 

扩展: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
View Code

 

框架Django番外篇