架构社区GITPython

Django框架总结

2018-06-20  本文已影响54人  月下独酌123

一、Django框架前言知识:

1、C/S和B/S的区别:

2、HTTP协议(超文本传输协议)

3、URL构成:

http://www.aspxfans.com:8080/news/index.aspboard?ID=5&ID=24618&page=1#


1、协议部分:http
2、域名部分:www.aspxfans.com
3、端口部分:8080
4、虚拟目录部分:从域名后’的第一个"/"到最后一个"/"为止,news
5、文件名部分:从域名红的最后一个"/"开始到"?"结束,index.aspboard
6、锚部分:从"#"开始
7、参数部分:从"?"开始,参数都是键值对形式。

二、Django框架基本流程

1.png

1、配置虚拟环境:

pip 升级:python -m pip install -upgrade pip
virtualenv安装: pip install virtualenv
virtualenvwrapper安装:pip install virtualenvwrapper-win
设置 WORK_HOME环境变量:设置虚拟环境的路径,将虚拟环境的文件目录添加到环境变量中 :WORK_HOME = D: test/virtualenv

pip 安装:sudo apt install python3-pip
pip 升级:sudo python3 -m pip install --upgrade pip
Virtualenv 安装:sudo python3 -m pip install
virtualenvwrapper 安装:sudo python3 -m pip install
打开~/.bashrc 文件:
cd /usr/local/bin
sudo gedit virtualenvwrapper.sh
在结尾添加:

export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/workspace
source /usr/local/bin/virtualenvwrapper.sh

然后执行: source ~/.bashrc
将设置在文件中的配置信息马上生效,而不需要经过重启。
所有的虚拟环境,都位于/home/.virtualenvs 目录下


报错: /usr/bin/python: No module named virtualenvwrapper
原因: Ubuntu 安装了 2.7 和 3.x 两个版本的 python,在安装时使用的是 sudo pip3 install virtualenvwrapper
在运行的时候默认使用的是 python2.x,但在 python2.x 中不存在对应的模块。
解决办法: 增加此环境变量:VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
注意:在 ubuntu 下以点开头命名的文件和文件夹是隐藏的,如果需要修改它们,如何看见?按 ctrl+h.就能看见以点号开头的隐藏文件.

虚拟环境的相关操作:

创建:mkvirtualenv 虚拟环境名称
进入:workon 虚拟环境名称
退出:deactivate 虚拟环境名
删除:rmvirtualenv 虚拟环境名

2、安装mysql-python:

  python 2.7 :pip install mysql-python
  python 3.0:pip3  install pymysql

3、创建django项目:

django-admin startproject 项目名

4、创建django项目中的app:

cd 项目名
python manage.py startapp 应用名

5、配置setting文件:

1.修改数据库的相关配置:

 "ENGINE":"django.db.backends.mysql",
 "NAME":"数据库名",
 "USER":"root",
 "HOST":"localhost",
 "PORT":3306,
 "PASSWORD":"密码",

2.修改模版的配置:

在模版的配置文件中加入存放模版的路径
设置 TEMPLATES 的 DIRS 值:
'DIRS': [os.path.join(BASE_DIR, 'templates')]

3.修改静态文件的配置:

在setting中配置:
STATIC_URL = '/static/'
STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ]

6、注意:python3 无法正常使用 mysql 的解决办法

django 连接 mysql 默认驱动是 MySQLdb, MySQLdb 没有支持 python3 的版本,
在 django 项目配置文件同目录下的init.py 文件中加入以下代码:
import pymysql
pymysql.install_as_MySQLdb()

7、models.py的编写

from django.db import models
class BookInfo(models.Model):
      btitle = models.CharField(max_length=20)
      bpub_date = models.DateTimeField()
      def __str__(self):
            return "%d" % self.pk
class HeroInfo(models.Model):
      hname = models.CharField(max_length=20)
      hgender = models.BooleanField()
      hcontent = models.CharField(max_length=100)
      hBook = models.ForeignKey('BookInfo' ,on_delete=models.CASCADE)
      def __str__(self):
            return "%d" % self.pk

生成迁移文件,执行迁移

生成迁移之前,要把app应用添加到setting配置文件中的INSTALLED_APPS中

python manage.py makemigrations
python manage.py migrate

注意:

1.python3 无法正常使用 mysql 的解决办法

django 连接 mysql 默认驱动是 MySQLdb, MySQLdb 没有支持 python3 的版本
在 django 项目配置文件同目录下的init.py 文件中加入以下代码:

import pymysql
pymysql.install_as_MySQLdb()

2、 python3 外键定义报错

hBook = models.ForeignKey('BookInfo')
Django2.0 下运行会提示这样的错误:
typeError: init() missing 1 required positional argument:'on_delete'
解决办法:
hBook = models.ForeignKey('BookInfo',on_delete=models.CASCADE)

3、生成迁移文件报错

django.db.utils.InternalError:(1049,"Unknown database 'books'")
手工创建数据库 books

8、views.py的编写

在 django 中,视图对 WEB 请求进行回应
视图就是一个 Python 函数,被定义在 views.py 中
视图接收 reqeust 对象作为第一个参数,包含了请求的信息

from django.http import HttpResponse
    def index(request):
          return HttpResponse("home page test.")

说明:
1.第二行引入 HttpResponse,它是用来向网页返回内容。

  1. index()函数第一个参数必须是 request,与网页发来的请求有关,request 变量里面包含 get 或 post 的内容,用户浏览器,系统等信息在里面 。
  2. 函数返回了一个 HttpResponse 对象,最终显示几个字到网页上。

render简写

from django.shortcuts import render
from booktest.models import BookInfo
def index(reqeust):
       booklist = BookInfo.objects.all()
       return render(reqeust, 'booktest/index.html', {'booklist': booklist})
def detail(reqeust, id):
      book = BookInfo.objects.get(pk=id)
      return render(reqeust, 'booktest/detail.html', {'book': book})

URLconf

Django 使用正则表达式匹配请求的 URL,一旦匹配成功,则调用应用的视图。在 Django 中,定义 URLconf 包括正则表达式、视图两部分。
注意:只匹配路径部分,即除去域名、参数后的字符串
在 test1/urls.py 插入 booktest,使主 urlconf 连接到 booktest.urls 模块
url(r'^', include('booktest.urls')),
在 booktest 中的 urls.py 中添加 urlconf

from django.conf.urls import url
from . import views
urlpatterns = [
      url(r'^$', views.index),
      url(r'^([0-9]+)/$', views.detail),
]

urlpatterns 列表中来配置 url,每一个列表项就是一个由 url 函数的调用。
一个 project 中如果有多个 app,为避免 url 管理可能的混乱,在项目的 urls.py 用 include方法包含 myapp 中的 urls。

9、template.py的编写

<!DOCTYPE html>
<html>
<head>
  <title>首页</title>
</head>
<body>
  <h1>图书列表</h1>
  <ul>
  {%for book in booklist%}
    <li>
      <a href="{{book.id}}">
        {{book.btitle}}
      </a>
    </li>
  {%endfor%}
</ul>
</body>
</html>

定义 detail.html 模板

<!DOCTYPE html>
<html>
<head>
  <title>详细页</title>
</head>
<body>
  <h1>{{book.btitle}}</h1>
  <ul>
    {%for hero in book.heroinfo_set.all%}
    <li>{{hero.hname}}---{{hero.hcontent}}</li>
    {%endfor%}
  </ul>
</body>
</html>

10、启动服务器

python manage.py runserver ip:port
通过浏览器访问 http://127.0.0.1:8000/ 可进行访问服务器

11、创建超级管理员

python manage.py createsuperuser
编辑 settings.py 文件,设置编码、时区
默认值:

LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'

修改为:

LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'Asia/Shanghai'

向 admin 注册 booktest 的模型
打开 booktest/admin.py 文件,注册模型

from django.contrib import admin
from models import BookInfo
admin.site.register(BookInfo)

刷新管理页面,可以对 BookInfo 的数据进行增删改查操作
自定义管理页面
Django 提供了 admin.ModelAdmin 类
通过定义 ModelAdmin 的子类,来定义模型在 Admin 界面的显示方式

from django.contrib import admin
from models import BookInfo
class BookInfoAdmin(admin.ModelAdmin):
#list_display:显示字段,可以点击列头进行排序
list_display = ['id', 'btitle', 'bpub_date']
# list_filter: 过滤字段,过滤框会出现在右侧
list_filter = ['btitle']
# search_fields: 搜索字段,搜索框会出现在上侧
search_fields = ['btitle']
# list_per_page:分页,分页框会出现在下侧
list_per_page = 2
# fieldsets:属性分组
fieldsets = [
      ('基本信息', {'fields': ['btitle']}),
      ('更多信息', {'fields': ['bpub_date']}),
]
关联 BookInfor 对象
英雄和书是多对一的关系
from django.contrib import admin
from models import BookInfo,HeroInfo
class HeroInfoInline(admin.StackedInline):
model = HeroInfo
extra = 2 #额外显示关联的记录数
class BookInfoAdmin(admin.ModelAdmin):
      inlines = [HeroInfoInline]
      admin.site.register(BookInfo, BookInfoAdmin)

三、 Model

ORM 简介

ORM(Object-Relation Mapping)---对象关系映射:
它是MVC框架很重要的一部分,实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库。
这个中间件可以独立存在于框架之外,在MVT框架中可以将用python语言书写的模型类映射成数据库表,用python语言来代替复杂的SQL语句来对数据库进行CDRU操作,最后返回对应的对象和列表。
ORM分为两种:
1、DB First:数据里先创建表,然后根据表结构,生成对应的代码
2、Code First:先书写对应的代码,再执行代码生成对应数据库表
使用ORM的优点:
-摆脱复杂的 SQL 操作;
-让数据结构变得简洁;
-数据库迁移成本更低;

开发流程

1、在 models.py 中定义模型类,要求继承自 models.Model
2、把应用加入 settings.py 文件的 installed_app 项
3、生成迁移文件
4、 执行迁移生成表
5、使用模型类进行 crud 操作

定义属性

  1. 导入 from django.db import models
  2. 通过 models.Field 创建字段类型的对象,赋值给属性Python 之:
    对于重要数据都做逻辑删除,不做物理删除,实现方法是定义 isDelete 属性,类型为BooleanField,默认值为 False

字段类型

1.AutoField:一个根据ID自动增长的 IntegerField
Django会为表自动增长的主键列,如果使用设置的主键列,django不会再生成默认的主键列
id = models.AutoField(primary_key=True)
2.BooleanField:true/false字段
3.NullBooleanField:支持null、true、false三种
4.TextField:大文本字段,一般超过4000使用
5.CharField(max_length=字符长度):字符串类型
6.IntegerField:整型
7.DecimalField(max_digits=None,decimal_places=None): 十进制浮点型
-----DecimalField.max_digits:位数总数
-----DecimalField.decimal_paleces:小数点后的数字位数
8.FloatField:浮点型
9.DateField(auto_now=False,auto_now_add=False):日期类型
-----DateField.auto_now:每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为 false
-----DateField.auto_now_add:当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为 false
-----auto_now_add, auto_now, and default 这些设置是相互排斥的,他们之间的任何组合将会发生错误的结果,因此只能设置一个
10.TimeField:时间字段,参数如DateField所示
11.DateTimeField:时间日期字段,参数如DateField所示
12.FieField:上传文件字段
13.ImageField:图片字段
---------上传路径设置:

STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static')
]
MEDIA_ROOT=os.path.join(BASE_DIR,"static/media")

字段选项

null:如果为 True, Django 将空值以 NULL 存储到数据库中,默认值是 False
blank:如果为 True,则该字段允许为空白,默认值是 False
-----对比: null 是数据库范畴的概念, blank 是表单验证证范畴的
-----如果一个字段设置为 blank=True,表单验证时允许输入一个空值。而blank=False,则该项必需输入数据。
db_column:字段的名称,如果未指定,则使用属性的名称
db_index:若值为 True, 则在表中会为此字段创建索引
default:默认值
primary_key:若为 True, 则该字段会成为模型的主键字段
unique:如果为 True,该字段在表中必须有唯一的值
verbose_name 字段的一种说明,在 form 中不会显示,和 label 是这个 Field 在 form中会显示的文本提示
help_text:会在 form 表单控件中显示 help 文本

关系

1.OneToOneField:一对一关系,将字段定义在任意一端中
跨表访问数据库表:
——有外键字段的表:对象.外键字段
——无外键字段的表:对象.模型类小写
2.ForeignKey:一对多关系,将字段定义在多的一端中
跨表访问数据库表:
——有外键字段的表:对象.外键字段
——无外键字段的表:对象.模型类小写._set()
3.ManyToManyField:多对多关系,将字段定义在任意一端中
会在数据库中生成第三张表,例如:

class Host(models.Model):
  id = models.AutoField(primary_key=True)
  hostname = models.CharField(max_length=32)
  ip = models.GenericIPAddressField(protocol='ipv4')
  port = models.IntegerField()
  def __str__(self):
    return self.hostname

class Application(models.Model):
  name = models.CharField(max_length=32)
  r = models.ManyToManyField(to='Host') # 这个字段在表里不存在。

添加

a=Application('qq')
a.save()
h1=Host(hostname='host1',ip='192.168.1.20',port='8000')
h1.save()
h2=Host(hostname='host2',ip='192.168.1.21',port='8001')
h2.save()
h3=Host(hostname='host3',ip='192.168.1.22',port='8002')
h3.save()
a.r.add(1) #对第三张表添加 application_id=1,host_id=1

查询

a.r.all()

反向查询(在没有 ManyToManyField 字段的表中查)

h1.application_set.all()

元选项

——在模型类中定义类Meta,用于设置元信息
————元信息:db_table:定义数据库表名,推荐使用小写字母,数据库表有默认表名
———— ording:数据库表有默认排序,字符串前加-表示倒序,不加-表示正序

管理器Manager

管理器是 Django 的模型进行数据库的查询操作的接口,用于与数据库进行交互,Django应用的每个模型都拥有至少一个管理器当定义模型类时没有指定管理器,则 Django 会为模型类提供一个名为 objects 的管理器

自定义管理器:

继承 models.Manager
自定义管理器类主要用于两种情况
情况一:向管理器类中添加额外的方法:见下面“创建对象” 中的方式二
情况二:修改管理器返回的原始查询集:重写 get_queryset()方法
当为模型类指定管理器后, django 不再为模型类生成名为 objects 的默认管理器

class BookInfoManager(models.Manager):
    def get_queryset(self):
         return super(BookInfoManager,self).get_queryset().filter(isDelete=False)
class BookInfo(models.Model):
    ...
books = BookInfoManager()

查询

查询集表示从数据库中获取的对象集合返回查询集的方法,称为过滤器
过滤器基于所给的参数限制查询的结果,从 Sql 的角度,查询集和 select 语句等价,过滤器像 where 和 limit 子句,查询集是可迭代的对象.
过滤器:

查询集返回列表,可以使用下标的方式进行限制,等同于 sql 中的 limit 和 offset 子句,不支持负索引

条件查询

实现 where 子名,作为方法 filter()、 exclude()、 get()的参数
语法:属性名称__比较运算符=值
表示两个下划线,左侧是属性名称,右侧是比较类型
对于外键,使用“属性名_id” 表示外键的原始值
转义: like 语句中使用了%与,匹配数据中的%与,在过滤器中直接写,例如:
filter(title__contains="%")=>where title like '%%%',表示查找标题中包含%的

比较运算符

BookInfo.books.filter(bpub_date__year=1980)
BookInfo.books.filter(bpub_date__gt=date(1980, 12, 31))
BookInfo.books.filter(bpub_date__gt=date(1990, 12, 31))
注意:
为避免查询 month 和 day 结果为空,请在 setting.py 中设置:
USE_TZ = False

跨关联查询

语法:模型类名_属性名_比较,相当于SQL语句中inner join

聚合函数

使用aggregate()函数返回聚合函数的值
函数:Avg、Count、Max、Min、Sum

F对象

  1. 通常情况下我们更新数据时先从数据库里将原数据取出放在内存后,然后修改对应的值,最后保存到数据库。
    当框架中出现F对象时,django会使用SQL语句的方式取代标准的python操作,python唯一做的操作是生成一条SQL语句,在数据库中完成对对应属性的更改,这种方式可以在多并发的情况下提高操作的效率,减少多线程操作带来的风险。
  2. 可以使用F对象完成两个字段中值的比较,此外,F对象还能完成算数运算,例如:
    list.filter(bread__gte=F('bcommet') * 2)
    list.filter(bread__gte=F('bcommet'))
    list.filter(bpub_date__lt=F('bpub_date') + timedelta(days=1))

Q对象

在使用过滤器进行查询时,可以对查询条件进行限制,当有多个条件时,要使用Q对象够构造相应的语句。
构造符号:&(与)或者|(或) ~(非)

四、View

view1.png

视图的本质就是一个函数,被定义在view.py文件中,响应的可以是一张网页的HTML内容,一个重定向,一个404错误等

URLconf

在django框架中,提供了非常清晰简洁的url管理方法。
步骤:
1.在根级urls.py文件中加入 应用的url配置:
url('^user/',include('user.urls',namespace='user')),
2.在应用中新建urls.py文件:

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

app_name='user'
urlpatterns = [
   url('^register/',views.register,name='register'),
   url('^register_handle/',views.register_handle,name='register_handle'),
   url(r'^verifycode/$',viewsUtil.verify,name='verifycode'),
   url('^login/',views.login,name='login'),
   url('^login_handle/',views.login_handle,name='login_handle'),
]

include()方法

include(arg, namespace=None)

url()方法

def url(regex, view, kwargs=None, name=None)

编写 URLconf 的注意

http://www.qikuedu.com/python/1/?i=1&p=new,只匹配“python/1/” 部分
性能: urlpatterns 中的每个正则表达式在第一次访问它们时被编译,这使得系统相当快

匹配url过程:

先与主URLconf匹配,成功后再用剩余的部分与应用中的URLconf匹配

请求 http://127.0.0.1:8000/booktest/1/
用 booktest/1/与项目的 urls 匹配
在项目 urls.py 中的配置:
url(r'^booktest/', include('booktest.urls')),
去除匹配过的部分,剩余部分部分是: 1/
用“1/” 与 booktest 应用的 urls 匹配
url(r'^([0-9]+)/$', views.detail, name='detail'),

URL反向解析

from django.urls import reverse
from django.http import HttpResponseRedirect

def test(reqeust, id):
    return HttpResponseRedirect(reverse('booktest:detail', args=(1,)))

错误视图

404(page not found)视图

当抛出 Http404 异常时, Django 会加载一个特殊的 view 方法django.views.defaults.page_not_found 处理 404 错误。
它负责加载和渲染 404.html 模板文件。
这意味着我们必须在模板根目录定义 404.html 模板文件,该模板文件应用于所有的 404异常。
defaults.page_not_found(request, template_name='404.html')
默认的 404 视图将传递一个变量给模板: request_path,它是导致错误的 URL
如果 Django 检测 URLconf 中的每个正则表达式后没有找到匹配的内容将调用 404 视图

自定义404错误视图:
DEBUG = False
ALLOWED_HOSTS = ['*', ]
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
    找不到了
<hr/>
    {{request_path}}
</body>
</html>

500(server error)视图

当 view 代码发生运行时错误时, Django 将会调用默认地 view 方法
django.views.defaults.server_error, 该方法加载渲染 500.html 模板文件。
这意味着我们必须在模板根目录定义 500.html 模板文件,该模板文件应用于所有的服务器错误。
defaults.server_error(request, template_name='500.html')
默认的 500 视图不会传递变量给 500.html 模板
如果在 settings 中 DEBUG 设置为 True,那么将永远不会调用 500 视图,而是显示URLconf 并带有一些调试信息

400(bad request)视图

from django.views import defaults
defaults.bad_request(request, template_name='400.html')
错误来自客户端的操作
例如当用户进行的操作在安全方面可疑的时候,例如篡改会话 cookie

403(Forbidden)视图

某些恶意网站上包含链接、表单按钮或者JS,利用登录过的用户在浏览器的认证信息试图在网站上完成某些操作,这就是跨站攻击。为了防止跨站攻击,django中在提交表单时有跨站请求保护,因此要在提交表单时要添加Cross Site Request Forgery (跨站请求伪造),如果没有添加,则会报403错误,如图所示:


403.png
<input type='hidden' name='csrfmiddlewaretoken'
value='nGjAB3Md9ZSb4NmG1sXDolPmh3bR2g59' />

Request对象

HttpRequest对象

服务器接受到http协议请求后,会创建HttpRequest对象
视图函数的第一个参数是 HttpRequest对象,在django.http模块中定义了HttpRequest对象的API

属性

方法

QueryDict 对象

定义在 django.http.QueryDict,request 对象的属性 GET、 POST 都是 QueryDict 类型的对象。与 python 字典不同, QueryDict 类型的对象用来处理同一个键带有多个值的情况。

get()

根据键获取值,只能获取一个值;如果一个键同时拥有多个值,获取最后一个值

getlist()

将键的值以列表返回,可以获取一个键的多个值

GET属性

包含 get 请求方式的所有参数,与 url 请求地址中的参数对应,位于?后面
参数的格式是键值对,如 key1=value1
多个参数之间,使用&连接,如 key1=value1&key2=value2
键是开发人员定下来的,值是可变的

POST属性

包含 post 请求方式的所有参数
与 form 表单中的控件对应,控件要有 name 属性,则 name 属性的值为键, value 属性的值为键,构成键值对提交
对于 checkbox 控件, name 属性一样为一组,当控件被选中后会被提交,存在一键多值的情况,键是开发人员定下来的,值是可变

Response对象

HttpResponse对象

在 django.http 模块中定义了 HttpResponse 对象的 API
HttpRequest 对象由 Django 自动创建, HttpResponse 对象由程序员创建
不调用模板,直接返回数据。

属性

方法

子类HttpResponseRedirect

重定向,服务器跳转
return HttpResponseRedirect('http://www.baidu.com')

子类JsonResponse

返回 json 数据,一般用于异步请求
帮助用户创建 JSON 编码的响应
参数 data 是字典对象
JsonResponse 的默认 Content-Type 为 application/json

from django.http import JsonResponse
def index2(requeset):
    return JsonResponse({'list': 'abc'})
def search(request):  
    kw = request.GET.get('kw')  
    word = Cnword.objects.filter(words__startswith=kw).values('words')[0:10]  
    # 返回django.db.models.query.ValuesQuerySet对象  
    # word = Cnword.objects.filter(words__startswith=kw)[0:10]  
    # 返回django.db.models.query.QuerySet对象  
    if word:  
        word = list(word) #ValuesQuerySet对象需要先转换成list  
        data = json.dumps(word) # 把list转成json  
        # data = serializers.serialize("json", word) #django.db.models.query.QuerySet对象可以序列化  
        return HttpResponse(data) #返回json  
    return HttpResponse('false')  

不需要全部字段时,可以用values('字段名','字段名2')来要求返回的是哪些列的数据.但是返回来的是ValuesQuerySet对象而不是QuerySet对象.
ValuesQuerySet对象 不能用 serializers.serialize() 方法序列化成json 需要先转换成list 再用 json.dumps()方法序列化成json
如果是直接models.objects.filter()查询出来的queryset对象,要用serializers.serialize() 方法序列化成json

状态保持

http 协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状态,因此实现状态保持的方式:在客户端或服务器端存储与会话有关的数据,存储方式包括 cookie、 session,会话一般指 session 对象。

使用session

设置会话过期时间

set_expiry(value):设置会话的超时时间

存储会话的方式

可以使用 settings.py 的 CACHES 中指定 SESSION_ENGINE 项

SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 1
SESSION_REDIS_PASSWORD = '123'
SESSION_REDIS_PREFIX = 'session'

五、Template

模板处理步骤

Django处理模板分为两个阶段:

加载渲染模板的完整代码
from django.template import loader,RequestContext
from django.http import HttpResponse

def index(request):
  tem = loader.get_template('template/index.html')
  context = {}
  return HttpResponse(tem.render(context))
快捷函数

为了减少加载模板、渲染模板的重复代码,django提供了快捷函数

render_to_string("")
render(request,'模板',context)

模板语言

变量名

标签

语法:{% tag %}

for标签

{% for item in item_list %}
  代码块
{% empty %}
  代码块
{% endfor %}

reversed标签:使得该列表被反向迭代

{% for item in item_list reversed%}

if标签

{% if ...... %}
代码块
{% elif ......%}
代码块
{% else %}
代码块
{% endif %}

逻辑运算符:and、or、not

注释标签

多行注释:{% comment %}

include标签:加载模板并以标签内的参数渲染

{%include "foo/bar.html" %}

url标签

csrf_token标签:这个标签用于跨站请求伪造

{% csrf_token%}

过滤器

模板继承

语法:

注意:django框架中最多只有三层模板继承结构

会被转义的字符

< 会转换为&lt
> 会转换为&gt
' (单引号) 会转换为&#39
" (双引号)会转换为 &quot
& 会转换为 &amp

关闭转义

{% autoescape off %}
{{ body }}
{% endautoescape %}

六、其他

验证码

详细文档参考: http://pillow.readthedocs.io/en/latest/

步骤:
实例代码:
from django.http import HttpResponse
from PIL import Image,ImageDraw,ImageFont
import random
import io
# Create your views here.
def verify(request):
  # 定义变量,用于画面的背景色、宽、高
  bg_color = (random.randrange(20,100),random.randrange(20,100),255)
  width = 100
  height = 25
  # 创建画面对象
  im = Image.new('RGB',(width,height),bg_color)
  # 创建画笔对象
  draw = ImageDraw.Draw(im)
  # 调用画笔的 point()函数绘制噪点
  for i in range(100):
    xy = (random.randrange(0,width),random.randrange(0,height))
    fill = (random.randrange(0,255),255,random.randrange(0,255))
    draw.point(xy,fill=fill)
  # 定义验证码的备选值
  str1 = 'ABCD123EFGHIJK456LMNOPQRS789TUVWXYZ0'
  # 随机选取 4 个值作为验证码
  rand_str=""
  for i in range(4):
    rand_str = rand_str + str1[random.randrange(0,len(str1)-1)]
  print(rand_str)
  # 构造字体对象
  font = ImageFont.truetype('FZSTK.TTF',23)
  # 构造字体颜色
  fontcolor = (255,random.randrange(0,255),random.randrange(0,255))
  # 绘制 4 个字
  draw.text((5,2), rand_str[0], font=font, fill=fontcolor)
  draw.text((25, 2), rand_str[1], font=font, fill=fontcolor)
  draw.text((50, 2), rand_str[2], font=font, fill=fontcolor)
  draw.text((75, 2), rand_str[3], font=font, fill=fontcolor)
  # 释放画笔
  del draw
  # 存入 session,用于做进一步验证
  request.session['verifycode'] = rand_str
  print(request.session.get('verifycode'))
  # 将图片保存在内存中,文件类型为 png
  f = io.BytesIO()
  im.save(f,'png')
  # 将内存中的图片数据返回给客户端,MIME 类型为图片 png
  return HttpResponse(f.getvalue(), 'image/png')

View视图函数

def verify_page(request):
  verify(request)
  template = loader.get_template("verifycode/index.html")
  return HttpResponse(template.render())

显示验证码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <div>Hello world</div>
  <img id='verifycode' src="/verifycode/" alt="CheckCode"/>
</body>
</html>
扩展验证码

需求:点击“看不清,话一个”时,可以换一个新的验证码
View视图函数

from django.http import HttpResponse
from django.template import loader
from .viewsUtil import verify

def verify_page(request):
  verify(request)
  template = loader.get_template("verifycode/index.html")
  return HttpResponse(template.render())

def verifycodeValid(request):
  vc = request.POST['vc']
  if vc.upper() == request.session['verifycode']:
    return HttpResponse('ok')
  else:
    return HttpResponse('no')

Template模板
点击事件处理

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title</title>
<script type="text/javascript" src="/static/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(function () {
  $('#verifycodeChange').css('cursor', 'pointer').click(function () {
    $('#verifycode').attr('src', $('#verifycode').attr('src') + 1)
});
});
</script>
</head>
<body>
  <div>Hello world</div>
  <form method='post' action='/verifycodeValid/'>
    <input type="text" name="vc">
    <img id='verifycode' src="/verify/?1" alt="CheckCode"/>
    <span id='verifycodeChange'>看不清,换一个</span>
    <br>
    <input type="submit" value="提交">
  </form>
</body>
</html>

管理静态文件

STATIC_URL = '/static/'
STATICFILES_DIRS = [
  os.path.join(BASE_DIR,'static'),
]

分页

Paginator对象

Paginator(列表,int):返回分页对象,参数为列表数据,每面数据的条数

属性:
方法:

page(num):下标从1开始,如果提供的页码不存在,则抛出InvalidPage异常

Page对象

Page对象由Paginator对象的page()方法色和归纳成返回Page对象

属性
方法

富文本编辑器

TINYMCE_DEFAULT_CONFIG = {
'theme': 'advanced',
'width': 600,
'height': 400,
}
<script type="text/javascript">
  tinyMCE.init({
    'mode':'textareas',
    'theme':'advanced',
    'width':400,
    'height':100
});
</script>

全文检索

Django中提供了一个Haystack包,可以提供模块化的搜索,提供了一个有好的API,支持不同的后端搜索引擎,例如whoosh、solr、Xapian、Elasticsearc等
1、在虚拟环境中以次安装包
pip install django-haystack
pip install whoosh
pip install jieba
2、添加应用:将haystack添加到应用中
3、添加搜索引擎

HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'booktest.whoosh_cn_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
}
}

4、分页设置

HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10

设置对搜索结果的分页,每 10 项结果为一页。
5、索引生成设置

HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

这里设置实时更新索引
7、创建索引类
在应用目录下加你了search_indexes.py文件

from haystack import indexes
from booktest.models import HeroInfo
class HeroInfoIndex(indexes.SearchIndex,   indexes.Indexable):
  text = indexes.CharField(document=True, use_template=True)
  def get_model(self):
    return HeroInfo
  def index_queryset(self, using=None):
    return self.get_model().objects.all()

8、设置数据模板
在目录"templates/search/indexes/应用名称/"下创建"模型类名称_text.txt"文件

heroinfo_text.txt,这里列出了要对哪些列的内容进行检索
{{ object.hname }}
{{ object.hcontent }}
{{ object.hgender }}
这个数据模板的作用是对 HeroInfo. hname、HeroInfo. hcontent、HeroInfo. hgender
这三个字段建立索引,当检索的时候会对这三个字段做全文检索匹配,然后将匹配的结果排序后作为搜索结果返回

9、在项目的urls.py中添加url

urlpatterns = [
...
url(r'^search/', include('haystack.urls')),
]

10、创建搜索结果界面
在目录下'templates/search/'下建立search.html

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
  {% if query %}
    <h3>搜索结果如下:</h3>
    {% for result in page.object_list %}
      <a href="/{{ result.object.id }}/">{{ result.object.hname }}</a> <br/>
      {% empty %}
      <p>啥也没找到</p>
    {% endfor %}
    {% if page.has_previous or page.has_next %}
      <div>
        {% if page.has_previous %}
          <a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">
        {% endif %}&laquo; 上一页{% if page.has_previous %}</a>{% endif %}
          |
        {% if page.has_next %}
          <a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}下一页 &raquo;{% if page.has_next %}</a>
        {% endif %}
      </div>
    {% endif %}
  {% endif %}
</body>
</html>

11、修改搜索引擎为中文分词
复制 Lib\site-packages\haystack\backends\whoosh_backend.py 文件,粘贴到应用目录下(这里是 booktest)改名为whoosh_cn_backend.py

from jieba.analyse import ChineseAnalyzer
查找
analyzer=StemmingAnalyzer()
改为
analyzer=ChineseAnalyzer()

12、生成索引
python manage.py rebuild_index
13、在模板中创建搜索栏

<form method='get' action="/search/" target="_blank">
  <input type="text" name="q">
  <input type="submit" value="查询">
</form>

缓存

设置缓存

在setting文件中添加CACHES配置

CACHES={
  'default': {
    'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    'TIMEOUT': 60,
  }
}
from django.core.cache import cache
设置:cache.set(键,值,有效时间)
获取:cache.get(键)
删除:cache.delete(键)
清空:cache.clear()

缓存View视图

示例代码:

from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def index(request):
  return HttpResponse('hello1')

缓存模板片段

示例代码:

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
{% cache 500 hello %}
hello3
<!--hello2-->
{% endcache %}
</body>
</html>
上一篇下一篇

猜你喜欢

热点阅读