Django专题

一.   web框架的原理:

1.C/S架构和B/S架构

C/S:客户端与服务器

B/S:浏览器与服务器     web开发

         2.web开发的本质:

socket服务端:收发消息都是按照HTTP协议的格式,浏览器是属于socket客户端

                   1.互联网上两台机器之间通信:

                            需要IP,端口号,协议

                   2.协议知识点:

                            HTTP默认端口:80

                            HTTPS默认端口:443

                            HTTP请求/响应的步骤:

         3. 在浏览器地址栏键入URL,按下回车之后会经历以下流程:

                  1). 域名  -> DNS解析 -> IP地址 -> 服务端 -> 返回消息 -> 浏览器

                   2). 服务器把写好的HTML页面,返回给浏览器,浏览器按照HTML格式渲染(显示)

         4.请求和响应

                   1)HTTP协议中:

                   浏览器给服务端发送消息的过程叫请求(request)

                   服务器给浏览器回复消息的过程叫响应(response)

                   2)请求和响应的消息都必须遵循一个固定的格式

                   请求方法:

         HTTP状态码:

         请求格式:

         响应格式:

二.python中web框架的分类

         对于真实开发中的python web程序来说,分两部分:服务器程序和应用程序

         1)服务器程序:负责对socket服务器进行封装,并在请求到来时,对请求各种数据进行处理

         2)应用程序:负责具体的逻辑处理

         3)框架分类:

         a. 收发socket消息,按照HTTP协议解析消息  Web服务程序 wsgiref、gunicorn、uWSGI

         b. 字符串替换  实现动态页面

         c. 业务逻辑处理                                                                              

                   1. 自己实现a、b、c的

                            tornado

                   2. 自己实现b、c,使用别人的a

                            Django

                   3. 自己实现c,使用别人的a和b

                            Flask

         4)WSGI(Web Server Gateway Interface)

         就是一种规范,它定义了使用Python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦。

         常用的WSGI服务器有uwsgi、Gunicorn。而Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来做服务器。

三. Django安装

                   1. Django版本介绍

                            1. 注意LTS版本

                   2. 安装 也可以去清华源加载 pip install django = 1.11.11 –i 清华源地址

                            1. pip install Django==1.11.11(卸载django:pip uninstall django)

                           

                   3. 创建第一个Django项目

                            1. 命令行创建

                                     django-admin startproject 项目名

                            2. PyCharm

                                     File -> new Project -> 左侧选第二项,右侧第一项是路径,第二项是选python版本

                                     在新的PyCharm窗口打开新建的Django项目

                   4.目录介绍:

        

                   5. 启动Django项目

                            1. 命令行启动

                                     在Django项目的根目录下,执行下面的命令

                                     python manage.py runserver

                                     python manage.py runserver 8080

                                     停止:Ctrl + C

                            2. PyCharm启动

                                     点绿色三角

                                     注意左侧框中的名字一定要是项目名称!

四:Django框架的使用:

1.模板文件配置

         2.静态文件配置:

3.Django基础必备三件套

from django.shortcuts import HttpResponse,render,redirect

1)HttpResponse

         内部传入一个字符串参数,返回给浏览器

         把字符串的OK转成二进制,然后按照HTTP响应的格式要求返回

例: def index(request):

         #业务逻辑代码

         return HttpResponse(‘ok’)

2)render

         除request参数外还接收一个待渲染的模板文件和一个保存具体数据的字典参数.将数据填充进模板文件,最后把结果返回给浏览器

例:

         def index(request):

                   return render(request,’index.html’,{‘name’:’alex’,’hobby’:[‘烫头’,’泡吧’]})

                   打开文件,读取内容,替换特殊符号,按照响应格式返回

3)redirect

接收一个URL参数,表示跳转到指定的URL.

例:

         def index(request)

                   return redirect(‘/home/’)

redirect实际做的事:给浏览器返回一个特殊的响应(命令)
# 这个特殊的命令就是让浏览器再发一次请求,访问我指定的URL

1. 路径可以为相对路径('/book_list/'),绝对路径('https://www.luffycity.com')

注意:

搜索的时候get用的比较多,get直接将信息展现在URL上,表单提交的时候用POST

4)重温知识点:

form表单提交数据的三个要素

         1.from标签必须要有action和methon属性,上传文件需要额外指定enctype属性

         2.所有获取用户输入的标签必须放在form表单里,必须要有name属性

         3.必须要有submit按钮

5)request相关的属性

         1.request.method :返回的是请求的方法(全大写):GET/POST

         2.request.GET : 取得是URL里面的参数,类似于字典的数据结构

         3.request.POST:post取到提交的数据(form表单).类似于字典的数据结构

6)Django的模板语言(HTML中的特殊符号)

         {{变量名}}  进行替换:{‘变量名’:’XXOO’}

7)Django项目app :项目中又分了一级python包,不同的功能放到不同的包里面

         1.创建app

                   python manage.py startapp app01

         2.告诉Django创建了一个app

五.认识ORM(Object Relationship Model)     

         1)概念:对象关系映射模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术.ORM在业务逻辑层和数据库层之间充当了桥梁的作用.

         2)ORM优势:开发效率高,开发不用直接写sql语句,支持多种数据库,适配性好

                     缺点:执行效率低,OMG用多了SQL语句就不会写了,关系数据库相关技能退化.

         3)Model: 在Django中model是你数据的单一、明确的信息来源。它包含了你存储的数据的重要字段和行为。通常,一个模型(model)映射到一个数据库表.

        

六.Django中ORM的使用

         1.用处

         1).操作数据表

         2)..操作数据行

         2.使用

         1)手动创建一个数据库

                   create database mysite;

         2)告诉Django连接那个数据库

                   DATABASES = {

                                              'default': {

                                                        'ENGINE': 'django.db.backends.mysql',  # 连接数据库的类型

                                                        'NAME': 'mysite',  # 数据库名

                                                        'HOST': '127.0.0.1',  # 数据库主机地址

                                                        'PORT': 3306,  # 数据库的端口

                                                        'USER': 'root',

                                                        'PASSWORD': '',

                                               }

                                     }

         3)用什么连接数据库:

                   利用第三方的包.比如:pymysql 和 MySQLdb

                   告诉Django用pymysql模块代替默认的MySQLdb去连接MySQL数据库

                   和settings.py同级的__init__.py文件上,写上:

                   import pymysql

                   pymysql.install_as_MySQLdb()

         4)在app/models.py的文件中创建类

                   类必须继承models.Model

         5)两个命令:

                   1. python manage.py makemigrations   找个小本本把models.py的变更记录一下

                   2.python manage.py migrate  把上面的变更记录翻译成SQL语句,去数据库执行

         6)在用form表单使用POST模式提交数据时:需要注释47行

         3.ORM查询

                   User.objects.filter(email=’ ’,pwd = ‘ ‘ )

         4.ORM语句:

         1)类名.objects.all()      查询所有,返回一个列表

         2)类名.objects.filter()    查询匹配的项,返回一个列表 可以找多个

         3)类名.objects.get()     查询匹配的项,返回一个对象 只能找一个

         4)类名.objects.create(name=’’) 创建一个对象,,返回的就是刚创建的对象

         5)类名.objects.filter(id=).delete() 删除

         6)obj = 类名.objects.get(id=’ ’)

           obj.name = ‘新值’    修改对象的属性(修改数据行某个字段的值)

           obj.save()                  把修改同步到数据库 改自己的字段的时候

         7)ORM外键:

                   press = models.ForeignKey(to=’Press’,on_delete = models.CASCADE)

         5.模板语言2

         for 循环

                   {% for i in ret %}:逻辑相关的

                            {{i}}

                            {{forloop.counter}}   for循环从1开始计数

                            {{forloop.counter0}}  for循环从0开始计数

                   {% endfor %}

                   1)forloop.last

                            {% if forloop.last %}  序号最后一个

                   2)empty

                            {% if I in x %}

                            …..

                            {% empty %}  为空

                            ……内容

                            {% endfor %}

         {% %}逻辑相关的 {{}}:变量相关的

         If 判断

                   {% if 条件 %}

                            …….

                   {%  else  %}

                            …….

                   {% endif %}

        

         6.多对多关系列表

         1)表设计 SQL版

                   创建作者表

                   create table author(

                            id int primary key auto_increment,

                            name varchar(32) not null,

)

创建关联表

create table author2book(

         id int primary key auto_increment,

         author_id int not null,

         book_id int not null,

         constraint fk_author foreign key(author_id) references author(id)

         on delect CASCADE

         on update CASCADE,

         constraint fk_book foreign key(book_id) references book(id)

         on delete CASCADE on update CASCADE,

ORM版

第一版:自己创建第三张表

第二版:

class Author(models.Model):

         id = models.AutoField(primary_key = True)

         name = models.CharField(max_length = 32)

         author = models.ManyToManyField(to=’Book’)

         2.作者的增删改查

                   1.查询

                   Author_obj.books  得到的只是一个关联关系,并不能拿到数据

                   Author_obj.books.all() 得到的和我这个作者关联的所有书籍对象列表

        

HTML页面:

2.添加:

request.POST.getlist(‘book’)   返回一个列表

3.编辑:

1.模板语言3:  in

         {% if book in author.books.all %}

2.ORM编辑多对多注意事项

         1.不能直接操作第三张关系表

         2.借助ORM给提供的方法

         1)all() 单纯 点 多对多的外键不能取到数据,只是关联关系Author_obj.books

                   需要: Author_obj.books.all() 得到数据列表

         2)add(id1,id2)也可以add(*列表):打散添加 多选时候用

         3)set([id1,id2])多选时候用

         4) clear()

4.上传

chunks 是一种方法,在括号里可以指定一次传多少

HTML页面:

7.Django框架介绍

1.MVC: 全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller),具有耦合性低、重用性高、生命周期成本低等优点。

Django框架的设计模式借鉴了MVC框架的思想,也是分成三部分,来降低各个部分之间的耦合性。

Django框架的不同之处在于它拆分的三部分为:Model(模型)、Template(模板)和View(视图),也就是MTV框架。

Model(模型):负责业务对象与数据库的对象(ORM)

    Template(模版):负责如何把页面展示给用户

View(视图):负责业务逻辑,并在适当的时候调用Model和Template

此外,Django还有一个urls分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

8.Django模板语言

1).基础语法

1.变量相关{{变量名}}

2逻辑相关{{%   %}}

2)变量相关

1变量命名:包括任何的字母数字以及下划线的组合,变量名称中不能有空格或标点符号.

2遇到 . 的查询顺序:

1)       字典查询

2)       属性或方法查询

3)       数字索引查询

3).注意事项:

1如果结果的值是可调用的,它将被无参数的调用,调用的结果将成为模板的值

2如果使用的变量不存在,默认为空

4).模板中支持的语法

Views中的代码:

        def template_test(request):

    l = [11, 22, 33]

    d = {"name": "alex"}

    class Person(object):

        def __init__(self, name, age):

            self.name = name

            self.age = age

        def dream(self):

            return "{} is dream...".format(self.name)

    Alex = Person(name="Alex", age=34)

    Egon = Person(name="Egon", age=9000)

    Eva_J = Person(name="Eva_J", age=18)

    person_list = [Alex, Egon, Eva_J]

    return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})

1列表中用索引取值

{{1.0}}

2取字典中的key值

{{d.name}}

3取对象的name属性

{{person_list.0.name}}

4操作只能调用不带参数的方法

{{person_list.0.dream}}

5).常用的内置filter(过滤器)

1过滤器作用:改变变量的显示

2过滤器语法:{{value|filter_name:参数}} 使用管道符”|”来应用过滤器

例: {{ name|lower }}会将name变量应用lower过滤器之后再显示它的值。lower在这里的作用是将文本全都变成小写。

3注意事项:

         1.过滤器支持’’链式’’操作.即一个过滤器的输出作为另一个过滤器的输入

         2,过滤器可以接受参数,只能有一个参数.例如{{ sss|truncatewords:30 }},这将显示sss的前30个词。

         3.过滤器参数包含空格的话,必须用引号包起来.例{{lst|join:’ - ’}}

         4.”|”左右没有空格

4过滤器介绍:

Django的模板语言中提供了大约六十个内置过滤器

         1).default:如果一个变量是false或者为空,使用给定的默认值,否则,使用变量的值

         {{value|default:’nothing’}}  如果value没有传值或者值为空显示nothing

         注:TEMPLATES的OPTIONS可以增加一个选项:string_if_invalid:'找不到',可以替代default的的作用

         2).length:返回值的长度,作用域字符串和列表

         {{value|length}} 如value=[‘a’,’b’,’c’,] 就显示3

         3).filesizeformat:将值格式化一个’人可读’的文件尺寸

         {{value|filesizeformat}} 如果value是123456789 输出将会是117.7M

         4).slice:切片

         {{value|slice:’2:-1’}}

         5).date:格式化时间

         {{value|date:”Y-m-d H:i:s”}}

         可用参数:

格式化字符

描述

示例输出

a

'a.m.'或'p.m.'(请注意,这与PHP的输出略有不同,因为这包括符合Associated Press风格的期间)

'a.m.'

A

'AM'或'PM'。

'AM'

b

月,文字,3个字母,小写。

'jan'

B

未实现。

 

c

ISO 8601格式。 (注意:与其他格式化程序不同,例如“Z”,“O”或“r”,如果值为naive datetime,则“c”格式化程序不会添加时区偏移量(请参阅datetime.tzinfo) 。

2008-01-02T10:30:00.000123+02:00或2008-01-02T10:30:00.000123如果datetime是天真的

d

月的日子,带前导零的2位数字。

'01'到'31'

D

一周中的文字,3个字母。

“星期五”

e

时区名称 可能是任何格式,或者可能返回一个空字符串,具体取决于datetime。

''、'GMT'、'-500'、'US/Eastern'等

E

月份,特定地区的替代表示通常用于长日期表示。

'listopada'(对于波兰语区域,而不是'Listopad')

f

时间,在12小时的小时和分钟内,如果它们为零,则分钟停留。 专有扩展。

'1','1:30'

F

月,文,长。

'一月'

g

小时,12小时格式,无前导零。

'1'到'12'

G

小时,24小时格式,无前导零。

'0'到'23'

h

小时,12小时格式。

'01'到'12'

H

小时,24小时格式。

'00'到'23'

i

分钟。

'00'到'59'

I

夏令时间,无论是否生效。

'1'或'0'

j

没有前导零的月份的日子。

'1'到'31'

l

星期几,文字长。

'星期五'

L

布尔值是否是一个闰年。

True或False

m

月,2位数字带前导零。

'01'到'12'

M

月,文字,3个字母。

“扬”

n

月无前导零。

'1'到'12'

N

美联社风格的月份缩写。专有扩展。

'Jan.','Feb.','March','May'

o

ISO-8601周编号,对应于使用闰年的ISO-8601周数(W)。 对于更常见的年份格式,请参见Y。

'1999年'

O

与格林威治时间的差异在几小时内。

'+0200'

P

时间为12小时,分钟和'a.m。'/'p.m。',如果为零,分钟停留,特殊情况下的字符串“午夜”和“中午”。 专有扩展。

'1 am','1:30 pm' / t3>,'midnight','noon','12:30pm' / T10>

r

RFC 5322格式化日期。

'Thu, 21 Dec 2000 16:01:07 +0200'

s

秒,带前导零的2位数字。

'00'到'59'

S

一个月的英文序数后缀,2个字符。

'st','nd','rd'或'th'

t

给定月份的天数。

28 to 31

T

本机的时区。

'EST','MDT'

u

微秒。

000000 to 999999

U

自Unix Epoch以来的二分之一(1970年1月1日00:00:00 UTC)。

 

w

星期几,数字无前导零。

'0'(星期日)至'6'(星期六)

W

ISO-8601周数,周数从星期一开始。

1,53

y

年份,2位数字。

'99'

Y

年,4位数。

'1999年'

z

一年中的日子

0到365

Z

时区偏移量,单位为秒。UTC以西时区的偏移量总是为负数,对于UTC以东时,它们总是为正。

-43200到43200

         6).safe:对HTML标签和JS等语法进行自动转义

         Value = “<a href=’#’>点我</a>”

         {{value|safe}}  可以把value自动转义成a标签,若没有safe则是字符串形式

         7).truncatechars

         如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“...”)结尾。

         {{value|truncatechars:9}} 参数:截断的字符数   (用于中文)

         8).truncatewords

         在一定数量的字后截断字符串.(用于英文)

         {{value|truncwords:9}}

         9).cut :移除value中所有的与给出的变量相同的字符串

         {{value|cut:’ ’}}

         如果value为’i love you’,那么输出’iloveyou’

         10).join: 使用字符串连接列表

         {{value|join:’-’}}

         11).timesince将日期格式设为自该日期起的时间(例如,“4天,6小时”)

         采用一个可选参数,它是一个包含用作比较点的日期的变量(不带参数,比较点为现在)。 例如,如果blog_date是表示2006年6月1日午夜的日期实例,并且comment_date是2006年6月1日08:00的日期实例,则以下将返回“8小时”:

         {{ blog_date|timesince:comment_date }}

         分钟是所使用的最小单位,对于相对于比较点的未来的任何日期,将返回“0分钟”。

         12).timeuntil

         似于timesince,除了它测量从现在开始直到给定日期或日期时间的时间。 例如,如果今天是2006年6月1日,而conference_date是保留2006年6月29日的日期实例,则{{ conference_date | timeuntil }}将返回“4周”。

         使用可选参数,它是一个包含用作比较点的日期(而不是现在)的变量。 如果from_date包含2006年6月22日,则以下内容将返回“1周”:

         {{ conference_date|timeuntil:from_date }}

         13)divisibleby  整除

         {% if forloop.counter|divisibleby:’2’ %}  整除2

         {% endif %}

         14).自定义filter

         1定义:

                   1. 在app目录下创建一个名为 templatetags 的python包

                   2. 在上面创建的包内部创建一个python文件: ooxx.py

                   3. 在ooxx.py文件中按照固定的格式注册的一个自定义的filter

                            from django import template

                            # 固定写法,生成一个注册实例对象

                            register = template.Library()

                            @register.filter()  # 告诉Django的模板语言我现在注册一个自定义的filter

                            def add_sb(value):

                                     """

                                     给任意指定的变量添加sb

                                     :param value: |左边被修饰的那个变量

                                     :return: 修饰后的变量内容

                                     """

                            return value + 'sb'

                            @register.filter()

                            def add_str(value, arg):

                                     return value + arg

         2使用:

                   1. 重启Django项目

                   2. 在HTML页面中:{% load python文件名 %}

                   3. {{ name|add_str:'大好人' }}

5)变量相关

         1.for循环:

         格式: <ul>

{% for user in user_list %}

                       <li>{{ user.name }}</li>

{% endfor %}

</ul>

         参数:

Variable

Description

forloop.counter

当前循环的索引值(从1开始)

forloop.counter0

当前循环的索引值(从0开始)

forloop.revcounter

当前循环的倒序索引值(从1开始)

forloop.revcounter0

当前循环的倒序索引值(从0开始)

forloop.first

当前循环是不是第一次循环(布尔值)

forloop.last

当前循环是不是最后一次循环(布尔值)

forloop.parentloop

本层循环的外层循环

for ……empty:为空的时候  {% empty %}

         2.if,elif和else  注意:不能连续判断,不支持算数运算 + - * / 用add,

         {% if a > b > c  %}….{% endif %}

         3.with 定义一个中间变量

         {% with dic.name as n %}

         {{ n }}

         {% endwith %}        

         相当于 {{ div.name }}

         4.csrf_token :用于跨站请求伪造保护,在表单中添加了一个隐藏的input标签

         在页面的form表单里面写上{% csrf_token %}   就不用注释setting47行了

9.母板

         1)继承母板

         在子页面中在页面最上方使用下面的语法来继承母板

         {% extends ‘book.html’ %}

         2)块

         通过在母板中使用{% block XXX %}…..{% endblock %}来定义’块’.

         {% block page-main %}

         内容

         {% endblock %}

         注意事项:

                   1.{% extends ‘base.html’  %} 写在第一行

                   2.{% extends name %} name写继承的母板的名字字符串

                  3.自定义的内容写在block中

                  4.定义多个block块 一般都有js css

10.组件

         定义:可以将常用的页面内容如导航栏,页尾信息等组件保存到单独的文件中,然后再需要使用的地方按语法导入(将一块代码进行封装)

         用法:1.写一段代码 nav.html

                   2.{%  include ‘nav.html’  %}

11.静态文件相关

         1.导入静态文件:

         {% load static %}  先导入static

第一种方式:{%  static ‘相对路径’  %} 去settings中获取STATIC_URL  '/static/' 和相对路径进行拼接

第二种方式:” {%  get_static_prefix  %}相对路径” 去settings中获取STATIC_URL  '/static/

         2.自定义simpletag :和自定义filter类似,只不过接收更灵活的参数

         定义注册simple_tag

         @register.simple_tag()

         def join_str(*args,**kwargs)

                   print(*args)

                   print(**kwargs)

                   return ‘-‘.join(args)

         使用自定义simple_tag

         {% load xxoo %}

         {% join_str ‘alex’ ‘is’ ‘dsb’ key1=’haha’ key2 = ‘hehe’ %}

         3.inclusion_tag 多用于返回html代码片段

12视图

         介绍:一个视图函数(类),简称视图,是一个简单的python函数(类),它接受web请求并返回web响应.

         响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。

无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。

         ------------------------------

         Django使用请求和响应对象来通过系统传递状态。

当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。

每个视图负责返回一个HttpResponse对象。

--------------------------------

         1.FBV和CBV

         FBV:function based view  写的函数

         CBV:class based view   类

         2.CBV的流程

                   1.定义CBV

                   from django.views import View

                   class AddPress(View):

                            def get(self,request):

                                     print(‘get’)

                                     print(self.request)

                                     return render(self.request,’add_press2.html’)

                            def post(self,request):

                                     print(‘post’)

                                     press_name = request.POST.get(‘name’)

                                     Press.objects.create(name=press_name)

                                     return redirect('/press_list/')

                  2.使用

                   url(r'^add_press/$', views.AddPress.as_view()),  # 添加出版社

                   3.流程

                            1.AppPress.as_view()   相当于指定view函数

                            2.当请求到来的时候执行view函数 :

                                     1. 实例化自己写的类   —— 》self

                                                        self = cls(**initkwargs)

                                               2. self.request = request

                                               3. 执行 self.dispatch(request, *args, **kwargs)

                                                        1. 执行父类中的dispatch方法

                                                                 1. 判断请求方式是否被允许

                                                                           1. 允许的情况

                                                                                    handler = 通过反射获取 get  post 方法

                                                                                   

                                                                           2. 不允许的情况

                                                                                    handler = 不允许的方法

                                                                           3. handler(request, *args, **kwargs)

                                                                 2. 返回HttpResponse对象

                                               4. 返回HttpResponse对象 给django

         3.给视图加装饰器

                  1.给FBV加装饰器

                   def wrapper(fn):

                       def inner(*args,**kwargs):

                           start = time.time()

                           ret = fn(*args,**kwargs)

                           print('结束时间%s' %(time.time()-start))

                           return ret

                       return inner

#添加班级

@wrapper

def classs_add(request):

                       if request.method == 'POST':

                           add_classs_name = request.POST.get('add_classs_name')

                           models.Classs.objects.create(name = add_classs_name)

                           return redirect('/classs_obj/')

                       return render(request,'classs_add.html')

                  2.给CBV加装饰器

                   from django.views import View

from django.utils.decorators import method_decorator

@method_decorator(wrapper,name='get')  #第二种方式

@method_decorator(wrapper,name='post') #第二种方式

class Classs_add(View):

   

@method_decorator(wrapper)  #第三种方式  post和get方法全部被装饰上装饰器,其他方式都是单个装饰

                        def dispatch(self, request, *args, **kwargs):

                           print('执行之前')

                           ret = super().dispatch(request, *args, **kwargs)

                           print('执行之后')

                           return ret

                   注意: # 使用CBV时要注意,请求过来后会先执行dispatch()这个方法,如果需要批量对具体的请求处理方法,如get,post等做一些操作的时候,这里我们可以手动改写dispatch方法,这个dispatch方法就和在FBV上加装饰器的效果一样。

                       @method_decorator(wrapper)     #第一种方式

                       def get(self,request):

                           return render(request,'classs_add.html')

                       @method_decorator(wrapper)     #第一种方式

                       def post(self,request):

                           add_classs_name = request.POST.get('add_classs_name')

                           models.Classs.objects.create(name=add_classs_name)

                           return redirect('/classs_obj/')

        

         4.Request对象和Response对象

                  1)request对象 请求

                   当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象。Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。

                   小知识点: http://127.0.0.1:8000/test2/?name=alex&id=2  网页拼接用&

                   2)请求相关的常用值

                   3)属性  所有的属性应该被认为是只读的,除非另有说明

****************************************************************************

        属性:
  django将请求报文中的请求行、头部信息、内容主体封装成 HttpRequest 类中的属性。
   除了特殊说明的之外,其他均为只读的。
0.HttpRequest.scheme
   表示请求方案的字符串(通常为http或https)
1.HttpRequest.body
  一个字符串,代表请求报文的主体。在处理非 HTTP 形式的报文时非常有用,例如:二进制图片、XML,Json等。
  但是,如果要处理表单数据的时候,推荐还是使用 HttpRequest.POST 。
  另外,我们还可以用 python 的类文件方法去操作它,详情参考 HttpRequest.read() 。
2.HttpRequest.path
  一个字符串,表示请求的路径组件(不含域名)。
  例如:"/music/bands/the_beatles/"
3.HttpRequest.method
  一个字符串,表示请求使用的HTTP 方法。必须使用大写。
  例如:"GET"、"POST"
4.HttpRequest.encoding
 
  一个字符串,表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置,默认为 'utf-8')。
   这个属性是可写的,你可以修改它来修改访问表单数据使用的编码。
   接下来对属性的任何访问(例如从 GET 或 POST 中读取数据)将使用新的 encoding 值。
   如果你知道表单数据的编码不是 DEFAULT_CHARSET ,则使用它。
5.HttpRequest.GET 
  一个类似于字典的对象,包含 HTTP GET 的所有参数。详情请参考 QueryDict 对象。
6.HttpRequest.POST
  一个类似于字典的对象,如果请求中包含表单数据,则将这些数据封装成 QueryDict 对象。
  POST 请求可以带有空的 POST 字典 —— 如果通过 HTTP POST 方法发送一个表单,但是表单中没有任何的数据,QueryDict 对象依然会被创建。
   因此,不应该使用 if request.POST  来检查使用的是否是POST 方法;应该使用 if request.method == "POST" 
  另外:如果使用 POST 上传文件的话,文件信息将包含在 FILES 属性中。
7.HttpRequest.COOKIES
  一个标准的Python 字典,包含所有的cookie。键和值都为字符串。
8.HttpRequest.FILES
  一个类似于字典的对象,包含所有的上传文件信息。
   FILES 中的每个键为<input type="file" name="" /> 中的name,值则为对应的数据。
  注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype="multipart/form-data" 的情况下才会
   包含数据。否则,FILES 将为一个空的类似于字典的对象。
9.HttpRequest.META
  一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例:
    CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。
    CONTENT_TYPE —— 请求的正文的MIME 类型。
    HTTP_ACCEPT —— 响应可接收的Content-Type。
    HTTP_ACCEPT_ENCODING —— 响应可接收的编码。
    HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。
    HTTP_HOST —— 客服端发送的HTTP Host 头部。
    HTTP_REFERER —— Referring 页面。
    HTTP_USER_AGENT —— 客户端的user-agent 字符串。
    QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。
    REMOTE_ADDR —— 客户端的IP 地址。
    REMOTE_HOST —— 客户端的主机名。
    REMOTE_USER —— 服务器认证后的用户。
    REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。
    SERVER_NAME —— 服务器的主机名。
    SERVER_PORT —— 服务器的端口(是一个字符串)。
   从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时,
    都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_  前缀。
    所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。
10.HttpRequest.user
  一个 AUTH_USER_MODEL 类型的对象,表示当前登录的用户。
  如果用户当前没有登录,user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例。你可以通过 is_authenticated() 区分它们。
    例如:
    if request.user.is_authenticated():
        # Do something for logged-in users.
    else:
        # Do something for anonymous users.
       user 只有当Django 启用 AuthenticationMiddleware 中间件时才可用。
     ------------------------------------------------------------------------------
    匿名用户
    class models.AnonymousUser
    django.contrib.auth.models.AnonymousUser 类实现了django.contrib.auth.models.User 接口,但具有下面几个不同点:
    id 永远为None。
    username 永远为空字符串。
    get_username() 永远返回空字符串。
    is_staff 和 is_superuser 永远为False。
    is_active 永远为 False。
    groups 和 user_permissions 永远为空。
    is_anonymous() 返回True 而不是False。
    is_authenticated() 返回False 而不是True。
    set_password()、check_password()、save() 和delete() 引发 NotImplementedError。
    New in Django 1.8:
    新增 AnonymousUser.get_username() 以更好地模拟 django.contrib.auth.models.User。
11.HttpRequest.session
  一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。
方法:
1.HttpRequest.get_host()
  根据从HTTP_X_FORWARDED_HOST(如果打开 USE_X_FORWARDED_HOST,默认为False)和 HTTP_HOST 头部信息返回请求的原始主机。
   如果这两个头部没有提供相应的值,则使用SERVER_NAME 和SERVER_PORT,在PEP 3333 中有详细描述。
  USE_X_FORWARDED_HOST:一个布尔值,用于指定是否优先使用 X-Forwarded-Host 首部,仅在代理设置了该首部的情况下,才可以被使用。
  例如:"127.0.0.1:8000"
  注意:当主机位于多个代理后面时,get_host() 方法将会失败。除非使用中间件重写代理的首部。
 
2.HttpRequest.get_full_path()
  返回 path,如果可以将加上查询字符串。
  例如:"/music/bands/the_beatles/?print=true"
3.HttpRequest.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
  返回签名过的Cookie 对应的值,如果签名不再合法则返回django.core.signing.BadSignature。
  如果提供 default 参数,将不会引发异常并返回 default 的值。
  可选参数salt 可以用来对安全密钥强力攻击提供额外的保护。max_age 参数用于检查Cookie 对应的时间戳以确保Cookie 的时间不会超过max_age 秒。
        复制代码
        >>> request.get_signed_cookie('name')
        'Tony'
        >>> request.get_signed_cookie('name', salt='name-salt')
        'Tony' # 假设在设置cookie的时候使用的是相同的salt
        >>> request.get_signed_cookie('non-existing-cookie')
        ...
        KeyError: 'non-existing-cookie'    # 没有相应的键时触发异常
        >>> request.get_signed_cookie('non-existing-cookie', False)
        False
        >>> request.get_signed_cookie('cookie-that-was-tampered-with')
        ...
        BadSignature: ...    
        >>> request.get_signed_cookie('name', max_age=60)
        ...
        SignatureExpired: Signature age 1677.3839159 > 60 seconds
        >>> request.get_signed_cookie('name', False, max_age=60)
        False
        复制代码
4.HttpRequest.is_secure()
  如果请求时是安全的,则返回True;即请求通是过 HTTPS 发起的。
5.HttpRequest.is_ajax()
  如果请求是通过XMLHttpRequest 发起的,则返回True,方法是检查 HTTP_X_REQUESTED_WITH 相应的首部是否是字符串'XMLHttpRequest'。
  大部分现代的 JavaScript 库都会发送这个头部。如果你编写自己的 XMLHttpRequest 调用(在浏览器端),你必须手工设置这个值来让 is_ajax() 可以工作。
  如果一个响应需要根据请求是否是通过AJAX 发起的,并且你正在使用某种形式的缓存例如Django 的 cache middleware, 
   你应该使用 vary_on_headers('HTTP_X_REQUESTED_WITH') 装饰你的视图以让响应能够正确地缓存。
 
4)Response对象响应
             from django.shorcuts import render,HttpResponse,redirect
             1.HttpResponse(‘字符串’)
             2.render(request,’html文件名’,{})
             3.redirect(跳转的地址)  两次请求 本质就给响应里面加了个响应头,即返回一个响应头,响应头的地址就是跳转的地址,浏览器看到这个地址后,才会接着去发一个请求
 
 
5.JsonResponse
      import json
      from django.http import JsonResponse
      def json_str(request):
         dic = {'name':'alex','age':20}
         # return HttpResponse(json.dumps(dic))  # Content-Type: text/html; charset=utf-8
         return JsonResponse(dic) # Content-Type: application/json
使用json 和 JsonResponse的区别
json:接收到的仅仅是一个字符串,需要反序列化成字典 
JsonResponse:当成json的数据格式,自动转成js中的它的对象,字典的形式,会做自动的转换,不需要进行反序列化.
 
 
 
 
原文地址:https://www.cnblogs.com/ITdong-1/p/9762695.html