Django学习目录,Django框架周详授课

Django学习目录

Django 的安装

一、MVC框架和MTV框架

MVC,全名是Model View
Controller,是软件工程中的一种软件架构情势,把软件系统一分配为6在那之中央部分:

模型(Model)、视图(View)和调节器(Controller),具有耦合性低、重用性高、生命周期花费低端优点。

MVC的实质便是用壹种业务逻辑、数据、分界面彰显分离的主意协会代码,将业务逻辑聚焦到2个构件里面,

在改进和本性化定制界面及用户交互的同时,不需求再度编辑职业逻辑。

美高梅开户网址 1

 

想要更详细的询问MVC格局? >>
谈谈MVC模式

Django框架的M电视形式本质上与MVC框架未有啥分别,也是分成三部分,来下滑各种部分之间的耦合性。

Django框架的不一样之处在于它拆分的三片段为:Model(模型)、Template(模板)和View(视图),也正是M电视框架。

Python的WEB框架有Django、Tornado、Flask
等二种,Django相较与其余WEB框架其优势为:大而全,框架本人集成了O福睿斯M、模型绑定、模板引擎、缓存、Session等大多效益。

Django框架简要介绍

Django基础
>>点我

Django
目录解释、创设应用(app)、创设数量连接

Django的MTV模式

       Model(模型):担负作业对象与数据库的对象(OSportageM)

       Template(模版):担当什么把页面突显给用户

       View(视图):担当作业逻辑,并在适合的时候调用Model和Template

其它,Django还有八个urls分发器,它的成效是将一个个ULX570L的页面请求分发给分化的view管理,view再调用相应的Model和Template

本文将以下地点带我们无微不至精通Django框架,作者使用的版本为一.10.

ORM介绍

Django中ORM介绍
>>点我

Django 路由系统

Django框架图示

美高梅开户网址 2

 

  1. 流程

  2. 主导配备

  3. 路由系统
  4. 视图view
  5. 模板
  6. Model
  7. 中间件
  8. Form
  9. 证实系统
  10. CSRF
  11. 分页
  12. Cookie
  13. Seesion
  14. 缓存
  15. 序列化
  16. 信号
  17. admin

ORM表操作

Django中OPAJEROM表相关操作
>>点我

Django 视图系统

APP

三个Django项目得以分成很八个应用程式,用来隔开分离不一样功效模块的代码。

1、 Django流程介绍

模板系统

Django模板系统
>>点我

Django
模板(Template)系统(模板语言相关内容)

命令行创立

python manage.py startapp app01#各种app的名字

美高梅开户网址 3

 

MVC是分明的格局,即:将应用程序分解成三个组成都部队分:model(模型),view(视图),和
controller(调整 器)。个中:
     
M——管理应用程序的情况(常常存款和储蓄到数据库中),并约束更动状态的作为(可能叫做“业务规则”)。
     
C——接受外部用户的操作,遵照操作访问模型获取数据,并调用“视图”突显这个数据。调控器是将“模型”和“视图”隔开分离,并变为二者之间的维系纽带。
      V——负担把数量格式化后彰显给用户。

Django也是1个MVC框架。然则在Django中,调整器接受用户输入的有的由框架自行管理,所以
Django 里更爱戴的是模型(Model)、模板(Template)和视图(Views),称为
M电视机格局:

    M 代表模型(Model),即数据存取层。 该层管理与数码有关的保有业务:
如何存取、怎么着注脚有效性、包括哪些表现以及数据里面包车型客车涉嫌等。

    T 代表模板(Template),即表现层。 该层管理与表现成关的决定:
怎么样在页面或其余体系文书档案中开始展览体现。

    V 代表视图(View),即专门的职业逻辑层。
该层包罗存取模型及调取得当模板的有关逻辑。
你能够把它看作模型与模板之间的大桥。

 

路由系统

Django路由系统
>>点我

Django
模型(model)ORM操作

使用PyCharm创建

详细消息点击这里

在红尘弹出的指令窗口输入:

startapp app01

贰、 Django 基本配备

视图系统

Django视图系统
>>点我

Django
O纳瓦拉M的连锁操作

路由系统 

Django路由系统 >> 点小编    后续更新

1. 创建django程序

  • 终极命令:django-admin startproject sitename
     (在当前目录下开创贰个Django程序)
  • IDE创造Django程序时,本质上都以电动试行上述命令

其余常用命令:

  python manage.py runserver ip:port
 (运维服务器,暗中同意ip和端口为)

  python manage.py startapp appname  (新建 app)

  python manage.py syncdb  (同步数据库命令,Django
一.柒及以上版本必要用以下的下令)

  python manage.py makemigrations  (呈现并记下全体数据的改观)

  python manage.py migrate  (将改成更新到数据库)

  python manage.py createsuperuser  (创设一流助理馆员)

  python manage.py dbshell  (数据库命令行)

Django学习目录,Django框架周详授课。  python manage.py  (查看命令列表)

 

Cookie & Session

Django中的Cookie和Session
>>点我

 

Django
Cookie、Session和自定义分页

视图系统

Django视图系统
>> 点作者

2. 先后目录

美高梅开户网址 4

 

Django 中间件

模板

模板(Template)系统 >> 点小编   后续更新

三. 陈设文件

Django AJAX的使用

模型

  1. 模型(model)系统OHavalM 的着力介绍
  2. O猎豹CS陆M字段和字段参数
  3. O昂CoraM的常用操作
  4. ORM的F查询和Q查询,事务

a、数据库

帮助SQLite 3(暗许)、PostgreSQL 、MySQL、Oracle数据库的操作

美高梅开户网址 5美高梅开户网址 6

# 默认是SQLit 3 的配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# MySQL的配置

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'dbname',   #注意这里的数据库应该以utf-8编码
    'USER': 'xxx',
    'PASSWORD': 'xxx',
    'HOST': '',
    'PORT': '',
    }
}

# 对于python3的使用者们还需要再加一步操作
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替

# 如下设置放置的与project同名的配置的 __init__.py文件中

import pymysql
pymysql.install_as_MySQLdb()


# PostgreSQL配置
DATABASES = {
    'default': {
        'NAME': 'app_data',
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'USER': 'XXX',
        'PASSWORD': 'XXX'
    }


# Oracle配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'xe',
        'USER': 'a_user',
        'PASSWORD': 'a_password',
        'HOST': '',
        'PORT': '',
    }
}

切实配置

Django框架对于开辟者来说中度透明化,对于差异数据库的现实应用格局是1致的,更改数据库类型只需求改动上述配置就可以。

想要驾驭越多请戳这里

 

b、静态文件增添

美高梅开户网址 7美高梅开户网址 8

# 首先在项目根目录下创建static目录

# 接着在settings.py 文件下添加

STATIC_URL = '/static/'  # 默认已添加,使用静态文件时的前缀
STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'static'), #行末的逗号不能漏
    )

# 这样在template中就可以导入static目录下的静态文件啦

# 例:
<script src="/static/jquery-1.12.4.js"></script>

settings配置

 

Django form表单

3、 Django 路由系统

UGL450L配置(U奥德赛Lconf)就像是Django
所扶助网址的目录。它的原形是UTucsonL形式以及要为该UBMWX3L方式调用的视图函数之间的映射表;你正是以这种措施告知Django,对于那些UTiguanL调用这段代码,对于丰盛UHighlanderL调用这段代码。U途睿欧L的加载是从配置文件中初露。

美高梅开户网址 9

参数说明:

  • 二个正则表明式字符串
  • 一个可调用对象,经常为贰个视图函数或三个内定视图函数路线的字符串
  • 可选的要传递给视图函数的暗许参数(字典格局)
  • 一个可选的name参数

 

Django
内置的验证体系

1. 示例

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

说明:

  • 要捕获从ULacrosseL中的值,用括号括起来,会当参数传入 views 视图。
  • 未曾要求增添3个斜线,因为每种URAV四L都有。举个例子,它^articles不是^/articles
  • 'r'前面包车型地铁种种正则表明式字符串中是可选的,但建议。它报告Python字符串是“原始”
    -未有何样字符串中应有张开转义。

恳请示例:

  • 三个请求 /articles/2005/03/ 会相称上面列表中的第2条. Django
    会调用函数 views.month_archive(request, '2005', '03').
  • /articles/2005/3/ 不会合营上边列表中的任何条目款项,
    因为第二条的月度要求3个人数字.
  • /articles/2003/ 会相配上首先条而不是第叁条,因为门户差不多是奉公守法从上到下顺序而进展的,
    Django 会调用函数 views.special_case_2003(request)
  • /articles/2003 不会协作上边列表中的任何条约, 因为每一种UQashqaiL应该以 /
    结尾.
  • /articles/2003/03/03/ 会相称上最后一条. Django
    会调用函数 views.article_detail(request, '2003', '03', '03').

增补请求头常用的ContentType、文件上传

 

Django admin
组件使用

2. 命名组(Named groups)

在上头的简要例子中,并从未运用正则表明式分组,在越来越尖端的用法中,很有十分的大希望选取正则分组来相称UGL450L并且将分组值通过参数字传送递给view函数。

在Python的正则表达式中,分组的语法是 (?P<name>pattern),
name代表分组名,pattern表示一些相称正则.

那边是多少个总结的小例子:

# 正则知识
import re

ret=re.search('(?P<id>\d{3})/(?P<name>\w{3})','weeew34ttt123/ooo')

print(ret.group())
print(ret.group('id'))
print(ret.group('name'))
-------------------------------------
123/ooo
123
ooo

  

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

For example:

  • A request
    to /articles/2005/03/ 会调用函数 views.month_archive(request, year='2005',month='03'),
    而不是 views.month_archive(request, '2005', '03').
  • A request
    to /articles/2003/03/03/ 会调用函数 views.article_detail(request, year='2003',month='03', day='03').

广大写法实例:

美高梅开户网址 10

Django admin
源码解析

 

三. 二级路由(Including)

那倘使映射 url 太多怎么做,全写一个在  urlpatterns 显得繁琐,so
二级路由使用而生

from django.conf.urls import include, url

from apps.main import views as main_views
from credit import views as credit_views

extra_patterns = [
    url(r'^reports/$', credit_views.report),
    url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),
    url(r'^charge/$', credit_views.charge),
]

urlpatterns = [
    url(r'^$', main_views.homepage),
    url(r'^help/', include('apps.help.urls')),
    url(r'^credit/', include(extra_patterns)),
]

在地点那几个例子中,假若请求url为 /credit/reports/ 则会调用函数 credit_views.report().

 

应用二级路由也得以减少代码冗余,使代码尤其从简易懂

# 原始版本
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/history/$', views.history),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/edit/$', views.edit),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/discuss/$', views.discuss),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/permissions/$', views.permissions),
]


# 改进版本
from django.conf.urls import include, url
from . import views

urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/', include([
        url(r'^history/$', views.history),
        url(r'^edit/$', views.edit),
        url(r'^discuss/$', views.discuss),
        url(r'^permissions/$', views.permissions),
    ])),
]

  

四. 增加额外的参数

UCR-VLconfs 有一个钩子可以让您进入一些卓绝的参数到view函数中.

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

在上头的例子中,假如八个呼吁为 /blog/2005/, Django
将会调用函数l views.year_archive(request, year='2005',foo='bar').

内需专注的是,当您加上参数时,对应函数views.year_archive必须抬高三个参数,参数名也无法不命名字为foo,如下:

 

def year_archive(request, foo):
    print(foo)
    return render(request, 'index.html')

  

5. 外号的运用

url(r'^index',views.index,name='bieming')

url中还匡助name参数的安插,如若布署了name属性,在模板的文书中就能够利用name值来庖代相应的url值.

大家来看1个例证:

美高梅开户网址 11美高梅开户网址 12

urlpatterns = [
    url(r'^index',views.index,name='bieming'),
    url(r'^admin/', admin.site.urls),
    # url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    # url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    # url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),

]
###################

def index(req):
    if req.method=='POST':
        username=req.POST.get('username')
        password=req.POST.get('password')
        if username=='alex' and password=='123':
            return HttpResponse("登陆成功")



    return render(req,'index.html')

#####################

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#     <form action="/index/" method="post">#}
{#     这里只要使用bieming即可代替/index #}
     <form action="{% url 'bieming' %}" method="post">
         用户名:<input type="text" name="username">
         密码:<input type="password" name="password">
         <input type="submit" value="submit">
     </form>
</body>
</html>


#######################

name的应用

  

六. 点名view的默许配置

# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# View (in blog/views.py)
def page(request, num="1"):
    # Output the appropriate page of blog entries, according to num.
    ...

在上述的事例中,七个 U奥迪Q5L
情势指向同1个视图 views.page但首先图案不抓获从 U帕杰罗L
任李菲西。假设第多个格局匹配,该 page()函数将采用它的暗中认可参数 num"1"。假如第二图画相相称时, page()将选择别的 num值由正则表明式捕获。

 

4、 Django Views(视图函数)

http请求中发出三个大旨指标:

  http请求:HttpRequest对象

  http响应:HttpResponse对象

 

1. HttpRequest对象

当呼吁三个页面时,Django
创设3个 HttpRequest目标涵盖原数据的伸手。然后 Django
加载适当的视图,通过 HttpRequest作为视图函数的率先个参数。各类视图肩负重临1个HttpResponse目标。

美高梅开户网址 13美高梅开户网址 14

path:       请求页面的全路径,不包括域名

method:     请求中使用的HTTP方法的字符串表示。全大写表示。例如

                   if  req.method=="GET":

                             do_something()

                   elseif req.method=="POST":

                             do_something_else()

GET:         包含所有HTTP GET参数的类字典对象

POST:       包含所有HTTP POST参数的类字典对象

             服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
             HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
             if req.POST来判断是否使用了HTTP POST 方法;应该使用  if req.method=="POST"



COOKIES:     包含所有cookies的标准Python字典对象;keys和values都是字符串。

FILES:      包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中 
            name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:

            filename:      上传文件名,用字符串表示
            content_type:   上传文件的Content Type
            content:       上传文件的原始内容


user:       是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
             没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
             可以通过user的is_authenticated()方法来辨别用户是否登陆:
             if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
             时该属性才可用

session:    唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。

META:       一个标准的Python字典包含所有可用的HTTP头。可用标题取决于客户端和服务器,但这里是一些例子:

            CONTENT_LENGTH       – 请求体的长度(一个字符串)。
            CONTENT_TYPE         – 请求体的类型。
            HTTP_ACCEPT          - 为响应–可以接受的内容类型。
            HTTP_ACCEPT_ENCODING – 接受编码的响应
            HTTP_ACCEPT_LANGUAGE – 接受语言的反应
            HTTP_HOST            – 客户端发送的HTTP主机头。
            HTTP_REFERER         – 参考页面
            HTTP_USER_AGENT      – 客户端的用户代理字符串。
            QUERY_STRING         – 查询字符串,作为一个单一的(分析的)字符串。
            REMOTE_ADDR          – 客户端的IP地址
            REMOTE_HOST          – 客户端的主机名
            REMOTE_USER          – 用户通过Web服务器的身份验证。
            REQUEST_METHOD       – 字符串,如"GET"或"POST"
            SERVER_NAME          – 服务器的主机名
            SERVER_PORT          – 服务器的端口(一个字符串)。

HttpRequest对象属性

 

2. HttpResponse对象

对于HttpRequest对象的话,是由django自动创立的,不过,HttpResponse对象就亟须我们团结创制。各个view请求管理措施必须再次来到三个HttpResponse对象。

在HttpResponse对象上扩张的常用方法:

  • 页面渲染:render(推荐),render_to_response,
  • 页面跳转:redirect
  • locals:   能够直接将对应视图函数中具备的变量传给模板    

美高梅开户网址 15

值得注意的是对此页面渲染的法子中,render和render_to_response使用办法和成效类似,可是render效率更为有力,推荐应用

 

3. render()

render(requesttemplate_namecontext=Nonecontent_type=Nonestatus=Noneusing=None)[source]

构成给定的模版与三个加以的上下文,重返三个字典HttpResponse在渲染文本对象

所需的参数

 template_name 2个模板的施用或模板体系名称全称。如若系列是给定的,存在于第三个模板将被选用。

可选参数

context    一组字典的值增多到模板中。私下认可景况下,那是一个空的字典。

content_type    MIME类型用于转移文书档案。

status    为响应状态代码。暗中认可值为200

using    那个名字贰个模板引擎的利用将模板。

美高梅开户网址 16美高梅开户网址 17

from django.shortcuts import render

def my_view(request):
    # View code here...
    return render(request, 'myapp/index.html', {
        'foo': 'bar',
    }, content_type='application/xhtml+xml')

render示例

 

五、 模板

一. 模板的举办

模版的创设进程,对于模版,其实就是读取模版(当中嵌套着沙盘标签),然后将
Model 中获得的数额插入到模版中,最终将新闻再次回到给用户。

美高梅开户网址 18美高梅开户网址 19

# view.py

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


# index.html

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

</body>
</html>

示例

 

二.  模板语言

模板中也有友好的言语,该语言能够落成数量显示

  • {{ 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 }}

 小知识点:在模板语言中字典数据类型的取值是经过dict.xxx而不是dict[xxx]

 

三. 自定义标签

因为在模板语言中不可见做运算等一些稍显复杂的操作,所以在Django中提供了二种自定制标签,1种是simple_tag,一种是filter。

simple_tag: 大4传递参数,然而无法用作布尔推断

filter: 最多只好传递3个参数,能够看成布尔剖断

在这里根本介绍simple_tag类型,filter的达成类似

a、在app中创建templatetags模块

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

美高梅开户网址 20美高梅开户网址 21

#!/usr/bin/env python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe
from django.template.base import resolve_variable, Node, TemplateSyntaxError

register = template.Library()

@register.simple_tag
def my_simple_time(v1,v2,v3):
    return  v1 + v2 + v3

@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

示例

c、在运用自定义simple_tag的html文件中程导弹入此前创设的 xx.py 文件名

{% load xx %}

d、使用simple_tag

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

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

美高梅开户网址 22美高梅开户网址 23

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

示例

更加多见文书档案:

 

六、 Model

Django提供了多个抽象层(“Model”)来创设和治本Web应用程序的数据。

django中听从 Code Frist
的准绳,即:依据代码中定义的类来自动生成数据库表。

提到对象映射(Object Relational Mapping,简称OLANDM)。

 

1. 创建表

a、基本结构

from django.db import models

 class userinfo(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()
    memo = models.TextField()

美高梅开户网址 24美高梅开户网址 25

1、null=True
  数据库中字段是否可以为空
2、blank=True
  django的 Admin 中添加数据时是否可允许空值
3、primary_key = False
  主键,对AutoField设置主键后,就会代替原来的自增 id 列
4、auto_now 和 auto_now_add
  auto_now   自动创建---无论添加或修改,都是当前操作的时间
  auto_now_add  自动创建---永远是创建时的时间
5、choices
GENDER_CHOICE = (
        (u'M', u'Male'),
        (u'F', u'Female'),
    )
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
6、max_length
7、default  默认值
8、verbose_name  Admin中字段的显示名称
9、name|db_column  数据库中的字段名称
10、unique=True  不允许重复
11、db_index = True  数据库索引
12、editable=True  在Admin里是否可编辑
13、error_messages=None  错误提示
14、auto_created=False  自动创建
15、help_text  在Admin中提示帮助信息
16、validators=[]
17、upload-to

越来越多参数

美高梅开户网址 26美高梅开户网址 27

1、models.AutoField  自增列 = int(11)
  如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
2、models.CharField  字符串字段
  必须 max_length 参数
3、models.BooleanField  布尔类型=tinyint(1)
  不能为空,Blank=True
4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
  继承CharField,所以必须 max_lenght 参数
5、models.DateField  日期类型 date
  对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
6、models.DateTimeField  日期类型 datetime
  同DateField的参数
7、models.Decimal  十进制小数类型 = decimal
  必须指定整数位max_digits和小数位decimal_places
8、models.EmailField  字符串类型(正则表达式邮箱) =varchar
  对字符串进行正则表达式
9、models.FloatField  浮点类型 = double
10、models.IntegerField  整形
11、models.BigIntegerField  长整形
  integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }
12、models.IPAddressField  字符串类型(ip4正则表达式)
13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
  参数protocol可以是:both、ipv4、ipv6
  验证时,会根据设置报错
14、models.NullBooleanField  允许为空的布尔类型
15、models.PositiveIntegerFiel  正Integer
16、models.PositiveSmallIntegerField  正smallInteger
17、models.SlugField  减号、下划线、字母、数字
18、models.SmallIntegerField  数字
  数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField  字符串=longtext
20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField  字符串,地址正则表达式
22、models.BinaryField  二进制
23、models.ImageField   图片
24、models.FilePathField 文件

越来越多字段

美高梅开户网址 28美高梅开户网址 29

class UserInfo(models.Model):
        nid = models.AutoField(primary_key=True)
        username = models.CharField(max_length=32)
        class Meta:
            # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
            db_table = "table_name"

            # 联合索引
            index_together = [
                ("pub_date", "deadline"),
            ]

            # 联合唯一索引
            unique_together = (("driver", "restaurant"),)

            # admin中显示的表名称
            verbose_name

            # verbose_name加s
            verbose_name_plural

    更多:https://docs.djangoproject.com/en/1.10/ref/models/options/

元信息

美高梅开户网址 30美高梅开户网址 31

1.触发Model中的验证和错误提示有两种方式:
        a. Django Admin中的错误信息会优先根据Admiin内部的ModelForm错误信息提示,如果都成功,才来检查Model的字段并显示指定错误信息
        b. 调用Model对象的 clean_fields 方法,如:
            # models.py
            class UserInfo(models.Model):
                nid = models.AutoField(primary_key=True)
                username = models.CharField(max_length=32)

                email = models.EmailField(error_messages={'invalid': '格式错了.'})

            # views.py
            def index(request):
                obj = models.UserInfo(username='11234', email='uu')
                try:
                    print(obj.clean_fields())
                except Exception as e:
                    print(e)
                return HttpResponse('ok')

           # Model的clean方法是一个钩子,可用于定制操作,如:上述的异常处理。

    2.Admin中修改错误提示
        # admin.py
        from django.contrib import admin
        from model_club import models
        from django import forms


        class UserInfoForm(forms.ModelForm):
            username = forms.CharField(error_messages={'required': '用户名不能为空.'})
            email = forms.EmailField(error_messages={'invalid': '邮箱格式错误.'})
            age = forms.IntegerField(initial=1, error_messages={'required': '请输入数值.', 'invalid': '年龄必须为数值.'})

            class Meta:
                model = models.UserInfo
                # fields = ('username',)
                fields = "__all__"


        class UserInfoAdmin(admin.ModelAdmin):
            form = UserInfoForm


        admin.site.register(models.UserInfo, UserInfoAdmin)

进展文化

 

b、连表结构

  • 一对多:models.ForeignKey(其他表)
  • 多对多:models.ManyToManyField(其他表)
  • 一对一:models.OneToOneField(其他表)

选取场景:

  • 一对多:当一张表中创立1行数据时,有3个单选的下拉框(能够被另行选拔)
    诸如:成立用户新闻时候,须要选拔三个用户类型【普通用户】【金牌用户】【铂金用户】等。
  • 多对多:在某表中开创壹行数据是,有3个得以多选的下拉框
    譬如说:创制用户新闻,要求为用户钦命五个爱护
  • 一定:在某表中开创一行数据时,有2个单选的下拉框(下拉框中的内容被用过2遍就流失了
    例如:原有含十列数据的一张表保存相关音信,经过1段时间之后,拾列不能够满意急需,要求为本来的表再增添5列数据

美高梅开户网址 32美高梅开户网址 33

ForeignKey(ForeignObject) # ForeignObject(RelatedField)
to,                         # 要进行关联的表名
to_field=None,              # 要关联的表中的字段名称
on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为
- models.CASCADE,删除关联数据,与之关联也删除
- models.DO_NOTHING,删除关联数据,引发错误IntegrityError
- models.PROTECT,删除关联数据,引发错误ProtectedError
- models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
- models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
- models.SET,删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

def func():
    return 10

class MyModel(models.Model):
    user = models.ForeignKey(
        to="User",
        to_field="id"
    on_delete=models.SET(func),)
related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
# 如:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}

from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
db_constraint=True          # 是否在数据库中创建外键约束
parent_link=False           # 在Admin中是否显示关联数据


OneToOneField(ForeignKey)
to,                         # 要进行关联的表名
to_field=None               # 要关联的表中的字段名称
on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为

###### 对于一对一 ######
# 1. 一对一其实就是 一对多 + 唯一索引
# 2.当两个类之间有继承关系时,默认会创建一个一对一字段
# 如下会在A表中额外增加一个c_ptr_id列且唯一:
class C(models.Model):
    nid = models.AutoField(primary_key=True)
    part = models.CharField(max_length=12)

class A(C):
    id = models.AutoField(primary_key=True)
    code = models.CharField(max_length=1)

ManyToManyField(RelatedField)
to,                         # 要进行关联的表名
related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
# 如:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}

from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
symmetrical=None,           # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
# 做如下操作时,不同的symmetrical会有不同的可选字段
models.BB.objects.filter(...)

# 可选字段有:code, id, m1
class BB(models.Model):

code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=True)

# 可选字段有: bb, code, id, m1
class BB(models.Model):

code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=False)

through=None,               # 自定义第三张表时,使用字段用于指定关系表
through_fields=None,        # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=50)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(
        Person,
        through='Membership',
        through_fields=('group', 'person'),
    )

class Membership(models.Model):
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    inviter = models.ForeignKey(
        Person,
        on_delete=models.CASCADE,
        related_name="membership_invites",
    )
    invite_reason = models.CharField(max_length=64)
db_constraint=True,         # 是否在数据库中创建外键约束
db_table=None,              # 默认创建第三张表时,数据库中表的名称

字段以及参数

 

2. 操作表

a、基本操作

美高梅开户网址 34美高梅开户网址 35

# 增
    #
    # models.Tb1.objects.create(c1='xx', c2='oo')  增加一条数据,可以接受字典类型数据 **kwargs

    # obj = models.Tb1(c1='xx', c2='oo')
    # obj.save()

    # 查
    #
    # models.Tb1.objects.get(id=123)         # 获取单条数据,不存在则报错(不建议)
    # models.Tb1.objects.all()               # 获取全部
    # models.Tb1.objects.filter(name='seven') # 获取指定条件的数据

    # 删
    #
    # models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据

    # 改
    # models.Tb1.objects.filter(name='seven').update(gender='0')  # 将指定条件的数据更新,均支持 **kwargs
    # obj = models.Tb1.objects.get(id=1)
    # obj.c1 = '111'
    # obj.save()                                                 # 修改单条数据

基本操作

 

b、进阶操作(了不起的双下划线)

行使双下划线将字段和相应的操作连接起来

美高梅开户网址 36美高梅开户网址 37

# 获取个数
        #
        # models.Tb1.objects.filter(name='seven').count()

        # 大于,小于
        #
        # models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
        # models.Tb1.objects.filter(id__gte=1)              # 获取id大于等于1的值
        # models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
        # models.Tb1.objects.filter(id__lte=10)             # 获取id小于10的值
        # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

        # in
        #
        # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
        # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in

        # isnull
        # Entry.objects.filter(pub_date__isnull=True)

        # contains
        #
        # models.Tb1.objects.filter(name__contains="ven")
        # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
        # models.Tb1.objects.exclude(name__icontains="ven")

        # range
        #
        # models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and

        # 其他类似
        #
        # startswith,istartswith, endswith, iendswith,

        # order by
        #
        # models.Tb1.objects.filter(name='seven').order_by('id')    # asc
        # models.Tb1.objects.filter(name='seven').order_by('-id')   # desc

        # group by
        #
        # from django.db.models import Count, Min, Max, Sum
        # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
        # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

        # limit 、offset
        #
        # models.Tb1.objects.all()[10:20]

        # regex正则匹配,iregex 不区分大小写
        #
        # Entry.objects.get(title__regex=r'^(An?|The) +')
        # Entry.objects.get(title__iregex=r'^(an?|the) +')

        # date
        #
        # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
        # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

        # year
        #
        # Entry.objects.filter(pub_date__year=2005)
        # Entry.objects.filter(pub_date__year__gte=2005)

        # month
        #
        # Entry.objects.filter(pub_date__month=12)
        # Entry.objects.filter(pub_date__month__gte=6)

        # day
        #
        # Entry.objects.filter(pub_date__day=3)
        # Entry.objects.filter(pub_date__day__gte=3)

        # week_day
        #
        # Entry.objects.filter(pub_date__week_day=2)
        # Entry.objects.filter(pub_date__week_day__gte=2)

        # hour
        #
        # Event.objects.filter(timestamp__hour=23)
        # Event.objects.filter(time__hour=5)
        # Event.objects.filter(timestamp__hour__gte=12)

        # minute
        #
        # Event.objects.filter(timestamp__minute=29)
        # Event.objects.filter(time__minute=46)
        # Event.objects.filter(timestamp__minute__gte=29)

        # second
        #
        # Event.objects.filter(timestamp__second=31)
        # Event.objects.filter(time__second=2)
        # Event.objects.filter(timestamp__second__gte=31)

进阶操作

 

c、其余操作

美高梅开户网址 38美高梅开户网址 39

# extra
    #
    # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
    #    Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
    #    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
    #    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
    #    Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])

    # F
    #
    # from django.db.models import F
    # models.Tb1.objects.update(num=F('num')+1)


    # Q
    #
    # 方式一:
    # Q(nid__gt=10)
    # Q(nid=8) | Q(nid__gt=10)
    # Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
    # 方式二:
    # con = Q()
    # q1 = Q()
    # q1.connector = 'OR'
    # q1.children.append(('id', 1))
    # q1.children.append(('id', 10))
    # q1.children.append(('id', 9))
    # q2 = Q()
    # q2.connector = 'OR'
    # q2.children.append(('c1', 1))
    # q2.children.append(('c1', 10))
    # q2.children.append(('c1', 9))
    # con.add(q1, 'AND')
    # con.add(q2, 'AND')
    #
    # models.Tb1.objects.filter(con)


    # 执行原生SQL
    #
    # from django.db import connection, connections
    # cursor = connection.cursor()  # cursor = connections['default'].cursor()
    # cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    # row = cursor.fetchone()

别的操作

 

d、连表操作(了不起的双下划线)

动用双下划线和 _set
将表之间的操作连接起来

美高梅开户网址 40美高梅开户网址 41

class UserProfile(models.Model):
    user_info = models.OneToOneField('UserInfo')
    username = models.CharField(max_length=64)
    password = models.CharField(max_length=64)

    def __unicode__(self):
        return self.username


class UserInfo(models.Model):
    user_type_choice = (
        (0, u'普通用户'),
        (1, u'高级用户'),
    )
    user_type = models.IntegerField(choices=user_type_choice)
    name = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    address = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name


class UserGroup(models.Model):

    caption = models.CharField(max_length=64)

    user_info = models.ManyToManyField('UserInfo')

    def __unicode__(self):
        return self.caption


class Host(models.Model):
    hostname = models.CharField(max_length=64)
    ip = models.GenericIPAddressField()
    user_group = models.ForeignKey('UserGroup')

    def __unicode__(self):
        return self.hostname

表结构实例

美高梅开户网址 42美高梅开户网址 43

user_info_obj = models.UserInfo.objects.filter(id=1).first()
print user_info_obj.user_type
print user_info_obj.get_user_type_display()
print user_info_obj.userprofile.password

user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
print user_info_obj.keys()
print user_info_obj.values()

1对一操作

美高梅开户网址 44美高梅开户网址 45

# 添加一对多
    dic = {
        "hostname": "名字1",
        "ip": "192.168.1.1",
        "user_group_id": 1,   # 加对象则为"user_group"
    }
    models.Host.objects.create(**dic)

    # 正向查一对多
    host_obj = models.Host.objects.all()
    print(type(host_obj),     # <class 'django.db.models.query.QuerySet'>
          host_obj)           # <QuerySet [<Host: 名字1>]>
    for item in host_obj:
        print(item.hostname)
        print(item.user_group.caption)
        print(item.user_group.user_info.values())
        # <QuerySet [{'name': 'nick', 'user_type': 1, 'id': 1, 'email': '630571017@qq.com', 'address': '128号'}]>

    usergroup_obj = models.Host.objects.filter(user_group__caption='标题1')
    print(usergroup_obj)


    # 反向查一对多
    usergroup_obj = models.UserGroup.objects.get(id=1)
    print(usergroup_obj.caption)
    ret = usergroup_obj.host_set.all()  # 所有关于id=1的host
    print(ret)

    obj = models.UserGroup.objects.filter(host__ip='192.168.1.1').\
        values('host__id', 'host__hostname')
    print(obj)      # <QuerySet [{'host__id': 1, 'host__hostname': '名字1'}]>

一对多

美高梅开户网址 46美高梅开户网址 47

user_info_obj = models.UserInfo.objects.get(name='nick')
user_info_objs = models.UserInfo.objects.all()

group_obj = models.UserGroup.objects.get(caption='CTO')
group_objs = models.UserGroup.objects.all()

# 添加数据
#group_obj.user_info.add(user_info_obj)
#group_obj.user_info.add(*user_info_objs)

# 删除数据
#group_obj.user_info.remove(user_info_obj)
#group_obj.user_info.remove(*user_info_objs)

# 添加数据
#user_info_obj.usergroup_set.add(group_obj)
#user_info_obj.usergroup_set.add(*group_objs)

# 删除数据
#user_info_obj.usergroup_set.remove(group_obj)
#user_info_obj.usergroup_set.remove(*group_objs)

# 获取数据
#print group_obj.user_info.all()
#print group_obj.user_info.all().filter(id=1)

# 获取数据
#print user_info_obj.usergroup_set.all()
#print user_info_obj.usergroup_set.all().filter(caption='CTO')
#print user_info_obj.usergroup_set.all().filter(caption='DBA')

    # 添加多对多
    # userinfo_id_1 = models.UserInfo.objects.filter(id=1)
    # usergroup_id_1 = models.UserGroup.objects.filter(id=1).first()
    # usergroup_id_1.user_info.add(*userinfo_id_1)

多对多操作

 

扩展:

a、自定义上传

美高梅开户网址 48美高梅开户网址 49

def upload_file(request):
    if request.method == "POST":
        obj = request.FILES.get('fafafa')
        f = open(obj.name, 'wb')
        for chunk in obj.chunks():
            f.write(chunk)
        f.close()
    return render(request, 'file.html')

示例

b、Form上传文件实例

美高梅开户网址 50美高梅开户网址 51

# HTML

       <form method="post" action="/view1/" enctype="multipart/form-data">
           <input type="file" name="ExcelFile" id="id_ExcelFile" />
           <input type="submit" value="提交" />
       </form>



# Form

class FileForm(forms.Form):
    ExcelFile = forms.FileField()

# Models

from django.db import models

class UploadFile(models.Model):
    userid = models.CharField(max_length = 30)
    file = models.FileField(upload_to = './upload/')
    date = models.DateTimeField(auto_now_add=True)

# Views

def UploadFile(request):
    uf = AssetForm.FileForm(request.POST,request.FILES)
    if uf.is_valid():
            upload = models.UploadFile()
            upload.userid = 1
            upload.file = uf.cleaned_data['ExcelFile']
            upload.save()

            print upload.file

View Code

c、ajax上传文件实例

美高梅开户网址 52美高梅开户网址 53

<div>
       {{ up.ExcelFile }}
       <input type="button" id="submitj" value="提交" />
   </div>


<script src="/static/js/jquery-2.1.4.min.js"></script>
<script>
    $('#submitj').bind("click",function () {
        var file = $('#id_ExcelFile')[0].files[0];
        var form = new FormData();
        form.append('ExcelFile', file);
         $.ajax({
                type:'POST',
                url: '/view1/',
                data: form,
                processData: false,  // tell jQuery not to process the data
                contentType: false,  // tell jQuery not to set contentType
                success: function(arg){
                    console.log(arg);
                }
            })
    })
</script>

HTML

美高梅开户网址 54美高梅开户网址 55

class FileForm(forms.Form):
    ExcelFile = forms.FileField()

Form

美高梅开户网址 56美高梅开户网址 57

from django.db import models

class UploadFile(models.Model):
    userid = models.CharField(max_length = 30)
    file = models.FileField(upload_to = './upload/')
    date = models.DateTimeField(auto_now_add=True)

Models

美高梅开户网址 58美高梅开户网址 59

from study1 import forms

def UploadFile(request):
    uf = AssetForm.FileForm(request.POST,request.FILES)
    if uf.is_valid():
            upload = models.UploadFile()
            upload.userid = 1
            upload.file = uf.cleaned_data['ExcelFile']
            upload.save()

            print upload.file

return render(request, 'file.html', locals())

View

 

七、中间件(MiddleWare)

django 中的中间件(middleware),在django中,中间件其实正是一个类,在伸手到来和得了后,django会依据自身的规则在适合的时机施行中间件中相应的不二等秘书技。

在django项目的settings模块中,有一个
MIDDLEWARE_CLASSES 变量,此中每八个要素就是叁在那之中间件,如下图。

美高梅开户网址 60

与mange.py在同一目录下的文件夹
wupeiqi/middleware下的auth.py文件中的Authentication类

中间件中得以定义几个章程,分别是:

  • process_request(self,request)
  • process_view(self, request, callback, callback_args,
    callback_kwargs)
  • 美高梅开户网址,process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

浅析源码得知前一个方式是从前以往进行的,后三个方法是从后往前实行的

美高梅开户网址 61

 所在此之前七个主意是呼吁进入时要通过的,而后多少个章程是伸手出去时要穿越的

一张图告诉您中间件的周转流程

美高梅开户网址 62

 

自定义中间件

壹、成立中间件类

class Middle_Test(object):

    def process_request(self,request):
        pass
    def process_view(self, request, callback, callback_args, callback_kwargs):
        i =1
        pass
    def process_exception(self, request, exception):
        pass

    def process_response(self, request, response):
        return response

  

二、注册中间件

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'sparks.middleware.auth.Middle_Test',
)

  

八、 Form

django中的Form一般有两种意义:

  • 输入html
  • 表明用户输入

美高梅开户网址 63美高梅开户网址 64

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from django import forms
from django.core.exceptions import ValidationError


def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误')


class PublishForm(forms.Form):

    user_type_choice = (
        (0, u'普通用户'),
        (1, u'高级用户'),
    )

    user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,
                                                                  attrs={'class': "form-control"}))

    title = forms.CharField(max_length=20,
                            min_length=5,
                            error_messages={'required': u'标题不能为空',
                                            'min_length': u'标题最少为5个字符',
                                            'max_length': u'标题最多为20个字符'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'标题5-20个字符'}))

    memo = forms.CharField(required=False,
                           max_length=256,
                           widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'详细描述', 'rows': 3}))

    phone = forms.CharField(validators=[mobile_validate, ],
                            error_messages={'required': u'手机不能为空'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手机号码'}))

    email = forms.EmailField(required=False,
                            error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'},
                            widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))

Form

美高梅开户网址 65美高梅开户网址 66

def publish(request):
    ret = {'status': False, 'data': '', 'error': '', 'summary': ''}
    if request.method == 'POST':
        request_form = PublishForm(request.POST)
        if request_form.is_valid():
            request_dict = request_form.clean()
            print request_dict
            ret['status'] = True
        else:
            error_msg = request_form.errors.as_json()
            ret['error'] = json.loads(error_msg)
    return HttpResponse(json.dumps(ret))

示例

 

利用Form还足以自动生成前端的input标签:

美高梅开户网址 67美高梅开户网址 68

from app01 import models
from django import forms

class Form1(forms.Form):
    user = forms.CharField(
        widget=forms.TextInput(attrs={'class':'c1'}), # 给标签添加属性
        error_messages={'required':'用户名不能为空'}, # 自定义错误输出
    )
    pwd = forms.CharField(max_length=4, min_length=2)
    email = forms.EmailField(error_messages={'required':'邮箱不能为空', 'invalid':'邮箱格式错误'})

    memo = forms.CharField(
        widget=forms.Textarea()
    )
    # user_type_choice = (
    #     (0, '普通用户'),
    #     (1, '高级用户'),
    # )
    user_type_choice = models.BookType.objects.values_list("id", "caption")
    # 这样并不能跟数据库实时同步,因为静态字段不更新
    book_type = forms.CharField(
        widget=forms.widgets.Select(choices=user_type_choice)
    )
    def __init__(self, *args, **kwargs):
        super(Form1, self).__init__(*args, **kwargs)
        # 让选项框跟数据库进行实时联动,解决上一行注释的问题
        self.fields['book_type'] = forms.CharField(
            widget=forms.widgets.Select(choices=models.BookType.objects.values_list("id", "caption"))
        )

form.py

美高梅开户网址 69美高梅开户网址 70

def form1(request):

    if request.method == "POST":
        # 获取请求做验证
        f = Form1(request.POST)
        if f.is_valid():
            print(f.cleaned_data)
        else:
            pass
            # print(f.errors['user'][0])
            # print(f.errors['pwd'][0])
        return render(request, "form1.html", {'error': f.errors, 'form':f})
    else:
        f = Form1()
        return render(request, 'form1.html',{'form':f})

views.py

美高梅开户网址 71美高梅开户网址 72

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .input-group{
            position: relative;
            padding: 23px;

        }
        .input-group input{
            width: 200px;
            display: inline-block;
        }
        .input-group span{
            display: inline-block;
            position: absolute;
            height: 20px;
            background-color:coral;
            color: white;
            bottom: 1px;
            left: 22px;
            width: 204px;


        }
    </style>
</head>
<body>
    <div>
        <form action="/form/" method="post">
            <div class="input-group">
{#                <input type="text" name="user"/>#}
                {{ form.user }}
                {% if error.user.0 %}
                {{ error.user.0 }}
                {% endif %}
            </div>
            <div class="input-group">
{#                <input type="text" name="pwd"/>#}
                {{ form.pwd }}
                {% if error.pwd.0 %}
                {{ error.pwd.0 }}
                {% endif %}
            </div>
            <div class="input-group">
                {{ form.email }}
                {% if error.email.0 %}
                {{ error.email.0 }}
                {% endif %}
            </div>
            <div class="input-group">
                {{ form.memo }}
                {% if error.memo.0 %}
                {{ error.memo.0 }}
                {% endif %}
            </div>
            <div class="input-group">
                {{ form.book_type }}
                {% if error.book_type.0 %}
                {{ error.book_type.0 }}
                {% endif %}
            </div>
            <input type="submit" value="提交"/>
        </form>
    </div>

</body>
</html>

form1.html

 

扩展:ModelForm

在动用Model和Form时,都急需对字段进行定义并钦点项目,通过ModelForm则足以省去From中字段的定义

美高梅开户网址 73美高梅开户网址 74

class AdminModelForm(forms.ModelForm):

    class Meta:
        model = models.Admin
        #fields = '__all__'
        fields = ('username', 'email')

        widgets = {
            'email' : forms.PasswordInput(attrs={'class':"alex"}),
        }

ModelForm

 

 

 

玖、 认证系统(auth)

auth模块是Django提供的正规化权限管理类别,能够提供用户地点验证,
用户组管理,并且能够和admin模块合作使用.

在INSTALLED_APPS中增添’django.contrib.auth’使用该APP, auth模块暗中同意启用.

model

from django.contrib.auth.models import User

# 数据库中该表名为auth_user.
CREATE TABLE "auth_user" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 
    "password" varchar(128) NOT NULL, "last_login" datetime NULL, 
    "is_superuser" bool NOT NULL, 
    "first_name" varchar(30) NOT NULL, 
    "last_name" varchar(30) NOT NULL,
    "email" varchar(254) NOT NULL, 
    "is_staff" bool NOT NULL, 
    "is_active" bool NOT NULL,
    "date_joined" datetime NOT NULL,
    "username" varchar(30) NOT NULL UNIQUE
)

新建用户

user = User.objects.create_user(username, email, password)
user.save()

# 不存储用户密码明文而是存储一个Hash值

表明用户

美高梅开户网址 75

from django.contrib.auth import authenticate

user = authenticate(username=username, password=password)

# 认证用户的密码是否有效, 若有效则返回代表该用户的user对象, 若无效则返回None.
# 该方法不检查is_active标志位.

美高梅开户网址 76

修改密码

美高梅开户网址 77

user.set_password(new_password)

# 以下实例为先认证通过后才可以修改密码
user = auth.authenticate(username=username, password=old_password)
if user is not None:
    user.set_password(new_password)
    user.save()

美高梅开户网址 78

登录

美高梅开户网址 79

from django.contrib.auth import login

# login向session中添加SESSION_KEY, 便于对用户进行跟踪:
'login(request, user)'

# login不进行认证,也不检查is_active标志位
# 实例
user = authenticate(username=username, password=password)
if user is not None:
    if user.is_active:
        login(request, user)

美高梅开户网址 80

剥离登入

美高梅开户网址 81

# logout会移除request中的user信息, 并刷新session

from django.contrib.auth import logout

def logout_view(request):
    logout(request)

美高梅开户网址 82

只允许登陆的用户访问

@login_required修饰器修饰的view函数会先经过session key检查是不是登六,
已报到用户能够平常的施行操作,
未登入用户将被重定向到login_url钦定的地方.

若未钦赐login_url参数, 则重定向到settings.LOGIN_URL

美高梅开户网址 83

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def userinfo(request):
    ...

# settings 配置
LOGIN_URL = '/index/'
# views
@login_required
def userinfo(request):
    ...

美高梅开户网址 84

 

 

10、 跨站请求伪造(csrf)

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

  在Django一.第10中学,为了防止BREACH攻击,对cookie-form类型的csrf做了几许改革,即在cookie和form中的token值是不一样样的

 

应用

一、普通表单

veiw中设置返回值:
     return render(request, 'xxx.html', data)

html中设置Token:
  {% csrf_token %}

  

2、Ajax

对此古板的form,能够由此表单的秘技将token再一次发送到服务端,而对于ajax的话,使用如下方式。

美高梅开户网址 85美高梅开户网址 86

# 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))

view.py

美高梅开户网址 87美高梅开户网址 88

# 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>

text.html

更多:

 

十一、 分页

壹. Django内置分页

美高梅开户网址 89美高梅开户网址 90

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

L = []
for i in range(999):
    L.append(i)

def index(request):
    current_page = request.GET.get('p')

    paginator = Paginator(L, 10)
    # per_page: 每页显示条目数量
    # count:    数据总个数
    # num_pages:总页数
    # page_range:总页数的索引范围,如: (1,10),(1,200)
    # page:     page对象
    try:
        posts = paginator.page(current_page)
        # has_next              是否有下一页
        # next_page_number      下一页页码
        # has_previous          是否有上一页
        # previous_page_number  上一页页码
        # object_list           分页之后的数据列表
        # number                当前页
        # paginator             paginator对象
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)
    return render(request, 'index.html', {'posts': posts})

views.py

美高梅开户网址 91美高梅开户网址 92

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<ul>
    {% for item in posts %}
        <li>{{ item }}</li>
    {% endfor %}
</ul>

<div class="pagination">

        {% if posts.has_previous %}
            <a href="?p={{ posts.previous_page_number }}">Previous</a>
        {% endif %}

            Page {{ posts.number }} of {{ posts.paginator.num_pages }}.

          {% if posts.has_next %}
              <a href="?p={{ posts.next_page_number }}">Next</a>
          {% endif %}


</div>
</body>
</html>

Html

美高梅开户网址 93美高梅开户网址 94

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger


class CustomPaginator(Paginator):
    def __init__(self, current_page, max_pager_num, *args, **kwargs):
        """
        :param current_page: 当前页
        :param max_pager_num:最多显示的页码个数
        :param args:
        :param kwargs:
        :return:
        """
        self.current_page = int(current_page)
        self.max_pager_num = max_pager_num
        super(CustomPaginator, self).__init__(*args, **kwargs)

    def page_num_range(self):
        # 当前页面
        # self.current_page
        # 总页数
        # self.num_pages
        # 最多显示的页码个数
        # self.max_pager_num
        print(1)
        if self.num_pages < self.max_pager_num:
            return range(1, self.num_pages + 1)
        print(2)
        part = int(self.max_pager_num / 2)
        if self.current_page - part < 1:
            return range(1, self.max_pager_num + 1)
        print(3)
        if self.current_page + part > self.num_pages:
            return range(self.num_pages + 1 - self.max_pager_num, self.num_pages + 1)
        print(4)
        return range(self.current_page - part, self.current_page + part + 1)


L = []
for i in range(999):
    L.append(i)

def index(request):
    current_page = request.GET.get('p')
    paginator = CustomPaginator(current_page, 11, L, 10)
    # per_page: 每页显示条目数量
    # count:    数据总个数
    # num_pages:总页数
    # page_range:总页数的索引范围,如: (1,10),(1,200)
    # page:     page对象
    try:
        posts = paginator.page(current_page)
        # has_next              是否有下一页
        # next_page_number      下一页页码
        # has_previous          是否有上一页
        # previous_page_number  上一页页码
        # object_list           分页之后的数据列表
        # number                当前页
        # paginator             paginator对象
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)

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

恢宏内置分页:views.py

美高梅开户网址 95美高梅开户网址 96

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

<ul>
    {% for item in posts %}
        <li>{{ item }}</li>
    {% endfor %}
</ul>

<div class="pagination">

{% if posts.has_previous %}
    <a href="?p={{ posts.previous_page_number }}">Previous</a>
{% endif %}

    {% for i in posts.paginator.page_num_range %}
        <a href="?p={{ i }}">{{ i }}</a>
    {% endfor %}

    {% if posts.has_next %}
        <a href="?p={{ posts.next_page_number }}">Next</a>
    {% endif %}



Page {{ posts.number }} of {{ posts.paginator.num_pages }}.


</div>
</body>
</html>

扩张内置分页:Html

2. 自定义分页

分页功用在种种网站都以必备的,对于分页来讲,其实就是依据用户的输入计算出相应在数据库表中的原初地点。

1、设定每页突显数据条数

二、用户输入页码(第二页、第一页…)

三、依据设定的每页展现条数和当前页码,计算出要求取数据表的开场地点

肆、在数据表中依照开首地方取值,页面上输出数据


要求又来了,供给在页面上海展览中心示分页的页面。如:[上1页][1][二][三][肆][5][下1页]

一、设定每页彰显数据条数

二、用户输入页码(第二页、第3页…)

3、设定呈现多少页号

四、获取当前数码总条数

5、依据设定显示多少页号和数据总条数总计出,总页数

6、依照设定的每页展现条数和当下页码,总计出供给取数据表的起首地方

7、在数据表中依据初叶地点取值,页面上输出数据

八、输出分页html,如:[上一页][一][二][叁][四][五][下1页]

美高梅开户网址 97美高梅开户网址 98

#!/usr/bin/env python
# _*_coding:utf-8_*_
from django.utils.safestring import mark_safe

class PageInfo(object):
    def __init__(self,current,totalItem,peritems=5):
        self.__current=current
        self.__peritems=peritems
        self.__totalItem=totalItem
    def From(self):
        return (self.__current-1)*self.__peritems
    def To(self):
        return self.__current*self.__peritems
    def TotalPage(self):  #总页数
        result=divmod(self.__totalItem,self.__peritems)
        if result[1]==0:
            return result[0]
        else:
            return result[0]+1

def Custompager(baseurl,currentPage,totalpage):  #基础页,当前页,总页数
    perPager=11
    #总页数<11
    #0 -- totalpage
    #总页数>11
        #当前页大于5 currentPage-5 -- currentPage+5
            #currentPage+5是否超过总页数,超过总页数,end就是总页数
        #当前页小于5 0 -- 11
    begin=0
    end=0
    if totalpage <= 11:
        begin=0
        end=totalpage
    else:
        if currentPage>5:
            begin=currentPage-5
            end=currentPage+5
            if end > totalpage:
                end=totalpage
        else:
            begin=0
            end=11
    pager_list=[]
    if currentPage<=1:
        first="<a href=''>首页</a>"
    else:
        first="<a href='%s%d'>首页</a>" % (baseurl,1)
    pager_list.append(first)

    if currentPage<=1:
        prev="<a href=''>上一页</a>"
    else:
        prev="<a href='%s%d'>上一页</a>" % (baseurl,currentPage-1)
    pager_list.append(prev)

    for i in range(begin+1,end+1):
        if i == currentPage:
            temp="<a href='%s%d' class='selected'>%d</a>" % (baseurl,i,i)
        else:
            temp="<a href='%s%d'>%d</a>" % (baseurl,i,i)
        pager_list.append(temp)
    if currentPage>=totalpage:
        next="<a href='#'>下一页</a>"
    else:
        next="<a href='%s%d'>下一页</a>" % (baseurl,currentPage+1)
    pager_list.append(next)
    if currentPage>=totalpage:
        last="<a href=''>末页</a>"
    else:
        last="<a href='%s%d'>末页</a>" % (baseurl,totalpage)
    pager_list.append(last)
    result=''.join(pager_list)
    return mark_safe(result)   #把字符串转成html语言

分页实例

计算,分页时需求做三件事:

  • 成立管理分页数据的类
  • 依据分页数据获取数据
  • 出口分页HTML,即:[上壹页][一][2][三][4][伍][下1页]

 

十二、 Cookie

1. 获取Cookie:

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

2. 设置Cookie:

1
2
3
4
5
6
7
8
9
10
11
12
13
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 hasn't been already.)
        path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
        domain=None,      Cookie生效的域名
        secure=False,     https传输
        httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

是因为cookie保存在客户端的微型Computer上,所以,JavaScript和jquery也能够操作cookie。

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

 

十三、 Session

Django中暗中认可补助Session,当中间提供了伍连串型的Session供开垦者使用:

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

1、数据库Session

美高梅开户网址 99美高梅开户网址 100

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")

        ...

View Code

2、缓存Session

美高梅开户网址 101美高梅开户网址 102

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

3、文件Session

美高梅开户网址 103美高梅开户网址 104

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、缓存+数据库Session

美高梅开户网址 105美高梅开户网址 106

数据库用于做持久化,缓存用于提高效率

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

b. 使用

    同上

View Code

5、加密cookie Session

美高梅开户网址 107美高梅开户网址 108

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

b. 使用

    同上

View Code

跟数据库的操作同样,在Django中区别缓存格局的使用方法是千篇壹律的,想要改动缓存的种类只需求更动上述相应安插就能够。

更加多参考:相撞这里 和 撞倒这里

推而广之: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是动态网站,全体每便请求均会去数据实行相应的操作,当程序访问量大时,耗时势必会愈发扎眼,最简便易行解决格局是利用:缓存,缓存将一个某部views的重返值保存至内存照旧memcache中,5分钟内再有人来拜访时,则不再去实行view中的操作,而是直接从内存依然Redis中在此之前缓存的剧情获得,并赶回。

Django中提供了6种缓存情势:

  • 支出调节和测试
  • 内存
  • 文件
  • 数据库
  • Memcache缓存(python-memcached模块)
  • Memcache缓存(pylibmc模块)

和数据库类似,缓存的具体操作都以一律的,使用区别的艺术只要求将配置改掉就可以

1、配置

a、开荒调节和测试

美高梅开户网址 109美高梅开户网址 110

# 此为开始调试用,实际内部不做任何操作
    # 配置:
        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、内存

美高梅开户网址 111美高梅开户网址 112

# 此缓存将内容保存至内存的变量中
    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
                'LOCATION': 'unique-snowflake',
            }
        }

    # 注:其他配置同开发调试版本

View Code

c、文件

美高梅开户网址 113美高梅开户网址 114

# 此缓存将内容保存至文件
    # 配置:

        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
                'LOCATION': '/var/tmp/django_cache',
            }
        }
    # 注:其他配置同开发调试版本

View Code

d、数据库

美高梅开户网址 115美高梅开户网址 116

# 此缓存将内容保存至数据库

    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
                'LOCATION': 'my_cache_table', # 数据库表
            }
        }

    # 注:执行创建表命令 python manage.py createcachetable

View Code

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

美高梅开户网址 117美高梅开户网址 118

# 此缓存使用python-memcached模块连接memcache

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': 'unix:/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
        }
    }

View Code

f、Memcache缓存(pylibmc模块)

美高梅开户网址 119美高梅开户网址 120

# 此缓存使用pylibmc模块连接memcache

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': '/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
        }
    }

View Code

 

2、应用

a. 全站使用

美高梅开户网址 121美高梅开户网址 122

使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存

    MIDDLEWARE = [
        'django.middleware.cache.UpdateCacheMiddleware',
        # 其他中间件...
        'django.middleware.cache.FetchFromCacheMiddleware',
    ]

    CACHE_MIDDLEWARE_ALIAS = ""
    CACHE_MIDDLEWARE_SECONDS = ""
    CACHE_MIDDLEWARE_KEY_PREFIX = ""

View Code

b. 单独视图缓存

美高梅开户网址 123美高梅开户网址 124

方式一:
        from django.views.decorators.cache import cache_page

        @cache_page(60 * 15)
        def my_view(request):
            ...

    方式二:
        from django.views.decorators.cache import cache_page

        urlpatterns = [
            url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
        ]

View Code

c、局地视图使用

美高梅开户网址 125美高梅开户网址 126

a. 引入TemplateTag

        {% load cache %}

    b. 使用缓存

        {% cache 5000 缓存key %}
            缓存内容
        {% endcache %}

View Code

注:若是出现多少个url相称同1个view函数的状态,缓存机制会依赖每三个例外的url做单独的缓存

更多:冲击这里

 

 

十五、 序列化

有关Django中的种类化首要行使在将数据库中搜索的数据重临给客户端用户,尤其的Ajax请求一般再次来到的为Json格式。

1. serializers

1
2
3
4
5
from django.core import serializers
 
ret = models.BookType.objects.all()
 
data = serializers.serialize("json", ret)

2. json.dumps

1
2
3
4
5
6
7
8
import json
 
#ret = models.BookType.objects.all().values('caption')
ret = models.BookType.objects.all().values_list('caption')
 
ret=list(ret)
 
result = json.dumps(ret)

是因为json.dumps时不知道该怎么办管理datetime日期,所以能够通过自定义管理器来做扩展,如:

美高梅开户网址 127美高梅开户网址 128

import json 
from datetime import date 
from datetime import datetime 

class JsonCustomEncoder(json.JSONEncoder): 

    def default(self, field): 

        if isinstance(field, datetime): 
            return o.strftime('%Y-%m-%d %H:%M:%S') 
        elif isinstance(field, date): 
            return o.strftime('%Y-%m-%d') 
        else: 
            return json.JSONEncoder.default(self, field) 


# ds = json.dumps(d, cls=JsonCustomEncoder) 

自定义示例

 

十六、 信号

Django中提供了“实信号调治”,用于在框架推行操作时解耦。通俗来讲,正是一些动作发生的时候,频域信号允许特定的发送者去唤醒部分接受者。

壹、Django内置时域信号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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内置的时域信号,仅需注册钦赐时限信号,当程序实行相应操作时,自动触发注册函数:

美高梅开户网址 129美高梅开户网址 130

    from django.core.signals import request_finished
    from django.core.signals import request_started
    from django.core.signals import got_request_exception

    from django.db.models.signals import class_prepared
    from django.db.models.signals import pre_init, post_init
    from django.db.models.signals import pre_save, post_save
    from django.db.models.signals import pre_delete, post_delete
    from django.db.models.signals import m2m_changed
    from django.db.models.signals import pre_migrate, post_migrate

    from django.test.signals import setting_changed
    from django.test.signals import template_rendered

    from django.db.backends.signals import connection_created


    def callback(sender, **kwargs):
        print("xxoo_callback")
        print(sender,kwargs)

    xxoo.connect(callback)
    # xxoo指上述导入的内容

View Code

 

二、自定义实信号

a. 定义并注册时域信号

# 自定制信号
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

def callback(sender, **kwargs):
    print("self-define")
    print(sender, kwargs)

pizza_done.connect(callback)

  

b. 触发复信号

from 路径 import pizza_done

pizza_done.send(sender='seven',toppings=123, size=456)

  

是因为放置非随机信号的触发者已经济合营并到Django中,所以其会活动调用,而对于自定义模拟信号则要求开采者在随机地点触发。

更多:冲击这里

 

十七、admin

django
amdin是django提供的三个后台处理页面,改管理页面提供周详的html和css,使得你在经过Model创设完数据库表之后,就能够对数码进行增加和删除改查,而采纳django
admin 则须要以下步骤:

  • 始建后台助理馆员
  • 配置url
  • 注册和布局django admin后台管理页面

注:不提议新手常常接纳admin,会产生依赖,主题的是model模块的操作!

1、成立后台管理员

python manage.py createsuperuser

二、配置后台处理url(暗中同意已配)

url(r'^admin/', include(admin.site.urls))

三、注册和布局django admin 后台管理页面

a、在admin中实行如下配置

美高梅开户网址 131美高梅开户网址 132

from django.contrib import admin

from app01 import  models

admin.site.register(models.UserType)
admin.site.register(models.UserInfo)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

View Code

b、设置数据表名称

美高梅开户网址 133美高梅开户网址 134

class UserType(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        verbose_name = '用户类型'
        verbose_name_plural = '用户类型'

View Code

c、打开表之后,设定暗许展现,供给在model中作如下配置

美高梅开户网址 135美高梅开户网址 136

class UserType(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):  # python3 is __str__(self)
        return self.name

View Code

d、为数据表增多找出效果

美高梅开户网址 137美高梅开户网址 138

from django.contrib import admin

from app01 import  models

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
    search_fields = ('username', 'email')

admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

View Code

e、增多高效过滤

美高梅开户网址 139美高梅开户网址 140

from django.contrib import admin

from app01 import  models

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
    search_fields = ('username', 'email')
    list_filter = ('username', 'email')



admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

View Code

更多:

 

 

再而三更新中……

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图