Django简介
什么是软件框架
举个简单的例子,对于一个公司来说,公司中有各个职能部门,每个部门各司其职,通过部门之间的配合来完成工作,这些部门就形成了一个公司的组织架构。从某种意义上来说,公司就是一种框架。那么对应到软件设计上来说,软件框架是由其中的各个模块组成的,每个模块负责特定的功能,模块与模块之间相互协作来完成软件开发。
一个公司,它是针对某一市场而成立的,而软件框架的设计,也是针对某一类软件问题而设计的,其目的主要是提高软件开发效率。
什么是MVC框架
MVC的全拼为Model-View-Controller,一种软件设计模式,是为了将传统的输入(input)、处理(processing)、输出(output)任务运用到图形化用户交互模型中而设计的。随着标准输入输出设备的出现,开发人员只需要将精力集中在业务逻辑的分析与实现上。后来被推荐为Oracle旗下Sun公司Java EE平台的设计模式,并且受到越来越多的使用ColdFusion和PHP的开发者的欢迎。现在虽然不再使用原来的分工方式,但是这种分工的思想被沿用下来,广泛应用于软件工程中,是一种典型并且应用广泛的软件架构模式。后来,MVC的思想被应用在了Web开发方面,被称为Web MVC框架。
MVC框架的核心思想是:解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容。
当前主流的开发语言如Java、PHP、Python中都有MVC框架。
Web MVC各部分的功能
M全拼为Model,主要封装对数据库层的访问,对数据库中的数据进行增、删、改、查操作。
V全拼为View,用于封装结果,生成页面展示的html内容。
C全拼为Controller,用于接收请求,处理业务逻辑,与Model和View交互,返回结果。
Django框架遵循MVC设计,并且有一个专有名词:MVT
MVT各部分的功能
M全拼为Model,与MVC中的M功能相同,负责和数据库交互,进行数据处理。
V全拼为View,与MVC中的C功能相同,接收请求,进行业务处理,返回应答。
T全拼为Template,与MVC中的V功能相同,负责封装构造要返回的html。
第一个Django程序
安装Django环境
pip install django
- 创建项目
django-admin startproject SMS(学校管理系统)
创建应用,这里应用的概念就相当于一个一个的功能模块,比如在一个电商网站中,用户管理、购物车、支付等等,就是一个一个的功能模块,我们用应用的概念将之区分开。
- 创建应用
python manage.py startapp studentToClass
目录结构介绍
-
*init.py_*是一个空文件,表示当前目录booktest可以当作一个python包使用。
-
tests.py文件用于开发测试用例,在实际开发中会有专门的测试人员,这个事情不需要我们来做。
-
models.py文件跟数据库操作相关。
-
views.py文件跟接收浏览器请求,进行处理,返回页面相关。
-
admin.py文件跟网站的后台管理相关。
-
migrations(与数据库相关)文件夹之后给大家介绍。
注册app
settings.py中注册
INSTALLED_APPS
简易开发服务器
在开发阶段,为了能够快速预览到开发的效果,django提供了一个纯python编写的轻量级web服务器,仅在开发阶段使用。
运行服务器命令如下:
python manage.py runserver ip:端口
例:
python manage.py runserver
模型设计
我们之前操作数据库是通过写sql语句,那么能不能不写sql语句就可以操作数据库呢? 可以,就是通过接下来要给大家讲的ORM框架。
ORM框架
O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思。在ORM框架中,它帮我们把类和数据表进行了一个映射,可以让我们通过类和类对象就能操作它所对应的表格中的数据。ORM框架还有一个功能,它可以根据我们设计的类自动帮我们生成数据库中的表格,省去了我们自己建表的过程。
django中内嵌了ORM框架,不需要直接面向数据库编程,而是定义模型类,通过模型类和对象完成数据表的增删改查操作。
使用django进行数据库开发的步骤如下:
- 1.在models.py中定义模型类
- 2.迁移
- 3.通过类和对象完成数据增删改查操作
1.定义模型类
模型类定义在models.py文件中,继承自models.Model类。
说明:不需要定义主键列,在生成时会自动添加,并且值为自动增长。
设计班级类
类名: classInfo
班级名称:class_name 六年级一班
班级号:class_id 601
学生类: studentInfo
学生学号:student_id
学生姓名:student_name
学生生日:student_birth
from django.db import models
# Create your models here.
class classInfo(models.Model):
class_id = models.IntegerField()
class_name = models.CharField(max_length=20)
class studentInfo(models.Model):
student_id = models.IntegerField()
student_name = models.CharField(max_length=20)
student_birth = models.DateField()
belong_class = models.ForeignKey('classInfo')
生成迁移
python manage.py makemigrations #生成迁移
python manage.py migrate # 迁移
后台管理系统
假设我们要设计一个新闻网站,我们需要编写展示给用户的页面,网页上展示的新闻信息是从哪里来的呢?是从数据库中查找到新闻的信息,然后把它展示在页面上。但是我们的网站上的新闻每天都要更新,这就意味着对数据库的增、删、改、查操作,那么我们需要每天写sql语句操作数据库吗?
如果这样的话,是不是非常繁琐,所以我们可以设计一个页面,通过对这个页面的操作来实现对新闻数据库的增删改查操作。那么问题来了,老板说我们需要在建立一个新网站,是不是还要设计一个页面来实现对新网站数据库的增删改查操作,但是这样的页面具有一个很大的重复性,那有没有一种方法能够让我们很快的生成管理数据库表的页面呢?有,那就是我们接下来要给大家讲的Django的后台管理。Django能够根据定义的模型类自动地生成管理页面。
汉化
LANGUAGE_CODE = 'zh-hans' #使用中国语言
TIME_ZONE = 'Asia/Shanghai' #使用中国上海时间
创建管理员并登陆
python manage.py createsuperuser
python manage.py runserver
http://127.0.0.1:8000/admin/
注册模型类
from django.contrib import admin
from booktest.models import BookInfo,HeroInfo
admin.site.register(classInfo)
admin.site.register(studentInfo)
自定义管理页面
from django.contrib import admin
from studentToClass.models import *
class classInfoAdmin(admin.ModelAdmin):
list_display = ['id', 'class_id', 'class_name']
class studentInfoAdmin(admin.ModelAdmin):
list_display = ['id','student_id','student_name','student_birth','belong_class']
# Register your models here.
admin.site.register(classInfo,classInfoAdmin)
admin.site.register(studentInfo,studentInfoAdmin)
视图
后台管理页面做好了,接下来就要做公共访问的页面了。当我们刚刚在浏览器中输入 http://127.0.0.1:8000/admin/ 之后,浏览器显示出了后台管理的登录页面,那有没有同学想过这个服务器是怎么给我们找到这个页面并返回呢?/admin/是我们想要请求的页面,服务器在收到这个请求之后,就一定对应着一个处理动作,这个处理动作就是帮我们产生页面内容并返回回来,这个过程是由视图来做的。
对于django的设计框架MVT,用户在URL中请求的是视图,视图接收请求后进行处理,并将处理的结果返回给请求者。
使用视图时需要进行两步操作:
* 1.定义视图函数
* 2.配置URLconf
1.定义视图
视图就是一个Python函数,被定义在views.py中。
视图的必须有一个参数,一般叫request,视图必须返回HttpResponse对象,HttpResponse中的参数内容会显示在浏览器的页面上。
打开studentToClass/views.py文件,定义视图index如下
from django.http import HttpResponse
def index(request):
return HttpResponse("index")
2.配置URLconf
查找视图的过程
请求者在浏览器地址栏中输入url,请求到网站后,获取url信息,然后与编写好的URLconf逐条匹配,如果匹配成功则调用对应的视图函数,如果所有的URLconf都没有匹配成功,则返回404错误。
一条URLconf包括url规则、视图两部分:
- url规则使用正则表达式定义。
- 视图就是在views.py中定义的视图函数。
需要两步完成URLconf配置:
- 1.在应用中定义URLconf
- 2.包含到项目的URLconf中
在booktest/应用下创建urls.py文件,定义代码如下:
from django.conf.urls import url
from studentToClass import views
urlpatterns = [
url(r'^$', views.index),
]
包含到项目中:打开test1/urls.py文件,为urlpatterns列表增加项如下:
url(r'^', include('studentToClass.urls')),
test1/urls.py文件完整代码如下:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^', include('studentToClass.urls')),
]
请求访问
视图和URLconf都定义好了,接下来在浏览器地址栏中输入网址:
http://127.0.0.1:8000/
网页显示效果如下图,视图被成功执行了。
模板
问题
如何向请求者返回一个漂亮的页面呢?
肯定需要用到html、css,如果想要更炫的效果还要加入js,问题来了,这么一堆字段串全都写到视图中,作为HttpResponse()的参数吗?这样定义就太麻烦了吧,因为定义字符串是不会出任何效果和错误的,如果有一个专门定义前端页面的地方就好了。
解决问题的技术来了:模板。
在Django中,将前端的内容定义在模板中,然后再把模板交给视图调用,各种漂亮、炫酷的效果就出现了。
创建模板
为应用booktest下的视图index创建模板index.html,目录结构如下图:
设置查找模板的路径:打开settings.py文件,设置TEMPLATES的DIRS值
'DIRS': [os.path.join(BASE_DIR, 'templates')],
定义模板
打开templtes/booktest/index.html文件,定义代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>班级列表</title>
</head>
<body>
<h1>{{title}}</h1>
{%for i in list%}
{{i}}<br>
{%endfor%}
</body>
</html>
在模板中输出变量语法如下,变量可能是从视图中传递过来的,也可能是在模板中定义的。
{{变量名}}
在模板中编写代码段语法如下:
{%代码段%}
视图调用模板
调用模板分为三步骤:
-
1.找到模板
-
2.定义上下文
-
3.渲染模板
打开浏览器刷新页面,显示效果如下图:
视图调用模板简写
视图调用模板都要执行以上三部分,于是Django提供了一个函数render封装了以上代码。 方法render包含3个参数:
- 第一个参数为request对象
- 第二个参数为模板文件路径
- 第三个参数为字典,表示向模板中传递的上下文数据
打开booktst/views.py文件,调用render的代码如下:
from django.shortcuts import render
# Create your views here.
from django.shortcuts import render
def index(request):
context = {'title':'班级列表','list':[1,2,3]}
return render(request,'index.html',context)
完成
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>班级列表</title>
</head>
<body>
<h1>{{title}}</h1>
{%for class in classList%}
<!--{{class.class.id}} {{class.class_id}}: {{class.class_name}}<br> -->
{{class.class_id}}: <a href="/{{class.id}}/">{{class.class_name}}</a><br>
{%endfor%}
</body>
</html>
detail.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{title}}</h1>
{%for student in studentList%}
{{student.student_id}},{{student.student_name}},{{student.student_birth}}<br>
{%endfor%}
</body>
</html>
views.py
from django.shortcuts import render
# Create your views here.
from django.shortcuts import render
from studentToClass.models import classInfo,studentInfo
def index(request):
# 班级列表
classList = classInfo.objects.all()
context = {'title': '班级列表', 'classList':classList}
return render(request,'index.html',context)
def detail(request,cid):
studentList = studentInfo.objects.filter(id=cid)
return render(request,'detail.html',{'studentList':studentList})
urls.py
from django.conf.urls import url
from studentToClass import views
urlpatterns = [
url(r'^$',views.index),
url(r'^(\d+)/$',views.detail)
]
模型
复习
- 定义模型类
- 迁移
- 生成迁移
定义模型类
-
模型类被定义在"应用/models.py"文件中,此例中为"studentToClass/models.py"文件。
-
模型类必须继承自Model类,位于包django.db.models中。
-
命名时不能是python的保留关键字
-
不允许使用连续的下划线(由于django的查询方式决定的)
-
通过字段类型的参数指定选项
字段类型
AutoField:自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性。
BooleanField:布尔字段,值为True或False。
NullBooleanField:支持Null、True、False三种值。
CharField(max_length=字符长度):字符串。
- 参数max_length表示最大字符个数。
TextField:大文本字段,一般超过4000个字符时使用。
IntegerField:整数。
DecimalField(max_digits=None, decimal_places=None):十进制浮点数。
- 参数max_digits表示总位数。
- 参数decimal_places表示小数位数。
FloatField:浮点数。
DateField[auto_now=False, auto_now_add=False]):日期。
- 参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,它总是使用当前日期,默认为false。
- 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false。
- 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误。
TimeField:时间,参数同DateField。
DateTimeField:日期时间,参数同DateField。
FileField:上传文件字段。
ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片
选项
- null:如果为True,表示允许为空,默认值是False。
- blank:如果为True,则该字段允许为空白,默认值是False。
- 对比:null是数据库范畴的概念,blank是表单验证范畴的。
- db_column:字段的名称,如果未指定,则使用属性的名称。
- db_index:若值为True, 则在表中会为此字段创建索引,默认值是False。
- default:默认值。
- primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用。
- unique:如果为True, 这个字段在表中必须有唯一值,默认值是False。
条件查询
查询等
exact:表示判等。
studentList = studentInfo.objects.filter(belong_class_id__exact=1)
#studentList = studentInfo.objects.filter(belong_class=1)
contains:是否包含。
说明:如果要包含%无需转义,直接写即可。
例:查询书名包含'传'的图书。
studentList = studentInfo.objects.filter(student_name__contains="小")
studentList = studentInfo.objects.filter(student_name__startswith="大")
studentList = studentInfo.objects.filter(student_name__endswith="牛")
startswith、endswith:以指定值开头或结尾。
isnull:是否为null。
例:查询书名不为空的图书。
studentList = studentInfo.objects.filter(student_name__isnull=False)
4) 范围查询
in:是否包含在范围内。
例:查询编号为1或3或5的图书
studentList = studentInfo.objects.filter(student_id__in=[60101,60202])
比较查询
gt、gte、lt、lte:大于、大于等于、小于、小于等于。
例:查询编号大于3的图书
studentList = studentInfo.objects.filter(student_id_gt=60103)
不等于的运算符,使用exclude()过滤器。
例:查询编号不等于3的图书
studentList = studentInfo.objects.exclude(student_id=60103)
例:查询1980年1月1日后发表的图书。
studentInfo.objects.filter(student_birth__gt="2019-08-04")
F对象
之前的查询都是对象的属性与常量值比较,两个属性怎么比较呢? 答:使用F对象,被定义在django.db.models中
from django.db.models import F
studentList = studentInfo.objects.filter(student_id__gt=F('belong_class_id'))
Q对象
多个过滤器逐个调用表示逻辑与关系,同sql语句中where部分的and关键字。
studentList = studentInfo.objects.filter(student_id__gt=60103, belong_class_id=1)
如果需要实现逻辑或or的查询,需要使用Q()对象结合|运算符,Q对象被义在django.db.models中。
语法如下:
Q(属性名__运算符=值)
例:查询阅读量大于20的图书,改写为Q对象如下。
from django.db.models import Q
...
studentList = studentInfo.objects.filter(Q(student_id__gt=60103))
Q对象可以使用&、|连接,&表示逻辑与,|表示逻辑或。
例:班级为2或者学号大于103
studentList = studentInfo.objects.filter(Q(student_id__gt=60103)|Q(belong_class_id=2))
Q对象前可以使用~操作符,表示非not。
例:查询编号不等于3的图书。
studentList = studentInfo.objects.filter(~Q(belong_class_id=2))
聚合函数
使用aggregate()过滤器调用聚合函数。聚合函数包括:Avg,Count,Max,Min,Sum,被定义在django.db.models中。
例:查询图书的总阅读量。
from django.db.models import Sum
...
studentList = studentInfo.objects.aggregate(Sum('student_id'))
注意aggregate的返回值是一个字典类型,格式如下:
{'聚合类小写__属性名':值}
如:{'student_id__sum': 360813}
使用count时一般不使用aggregate()过滤器。
例:查询图书总数。
studentList = studentInfo.objects.count()
注意count函数的返回值是一个数字。
查询集表示从数据库中获取的对象集合,在管理器上调用某些过滤器方法会返回查询集,查询集可以含有零个、一个或多个过滤器。过滤器基于所给的参数限制查询的结果,从Sql的角度,查询集和select语句等价,过滤器像where和limit子句。
返回查询集的过滤器如下:
- all():返回所有数据。
- filter():返回满足条件的数据。
- exclude():返回满足条件之外的数据,相当于sql语句中where部分的not关键字。
- order_by():对结果进行排序。
返回单个值的过滤器如下:
- get():返回单个满足条件的对象
- 如果未找到会引发"模型类.DoesNotExist"异常。
- 如果多条被返回,会引发"模型类.MultipleObjectsReturned"异常。
- count():返回当前查询结果的总条数。
- aggregate():聚合,返回一个字典。
判断某一个查询集中是否有数据:
- exists():判断查询集中是否有数据,如果有则返回True,没有则返回False。
两大特性
- 惰性执行:创建查询集不会访问数据库,直到调用数据时,才会访问数据库,调用数据的情况包括迭代、序列化、与if合用。
- 缓存:使用同一个查询集,第一次使用时会发生数据库的查询,然后把结果缓存下来,再次使用这个查询集时会使用缓存的数据。
限制查询集
可以对查询集进行取下标或切片操作,等同于sql中的limit和offset子句。
注意:不支持负数索引。
对查询集进行切片后返回一个新的查询集,不会立即执行查询。
如果获取一个对象,直接使用[0],等同于[0:1].get(),但是如果没有数据,[0]引发IndexError异常,[0:1].get()如果没有数据引发DoesNotExist异常。
示例:获取第1、2项,运行查看。
list=BookInfo.objects.all()[0:2]
视图
URLconf
用户通过在浏览器的地址栏中输入网址请求网站,对于Django开发的网站,由哪一个视图进行处理请求,是由url匹配找到的。
配置
1)在SMS/settings.py中通过ROOT_URLCONF指定url配置,默认已经有此配置。
2)打开SMS/urls.py可以看到默认配置。
注意点
-
在SMS/urls.py中进行包含配置,在各自应用中创建具体配置。
-
定义urlpatterns列表,存储url()对象,这个名称是固定的。
urlpatterns中的每个正则表达式在第一次访问它们时被编译,这使得运行很快。
语法
url()对象,被定义在django.conf.urls包中,有两种语法结构:
语法一:包含,一般在自定义应用中创建一个urls.py来定义url。
这种语法用于SMS/urls.py中,目的是将应用的urls配置到应用内部,数据更清晰并且易于维护。
url(正则,include('应用.urls'))
1)如示例在SMS/urls.py文件,包含booktest中的urls。
url(r'^',include('studentToClass.urls')),
- 如示例在SMS目录下创建urls.py文件。
语法二:定义,指定URL和视图函数的对应关系。
在应用内部创建urls.py文件,指定请求地址与视图的对应关系。
url(正则,'视图函数名称')
1)如示例在studentToClass/urls.py中创建首页的url,代码如下
from django.conf.urls import url
from booktest import views
urlpatterns=[
url(r'^$',views.index),
]
2)如示例在booktest/views.py中创建视图index
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("视图函数index")
获取值
请求的url被看做是一个普通的python字符串,进行匹配时不包括域名、get或post参数。 如请求地址如下:
http://127.0.0.1:8000/arg1
1)去除掉域名和参数部分,并将最前面的/去除后,只剩下如下部分与正则匹配。
arg1/
2)打开booktest/urls.py文件,定义与这个地址匹配的url如下:
url(r'^arg(\d+)/$',views.get_arg)
3)在booktest/views.py中创建视图show_arg。
def get_arg(request,arg):
return HttpResponse('arg%s'%arg)
4)启动服务器,输入上面的网址,浏览器中效果如下图。
可以在匹配过程中从url中捕获参数,每个捕获的参数都作为一个普通的python字符串传递给视图。
二
通过request获取
http://127.0.0.1:8000/arg99/?name=5
def get_arg(request,arg):
name = request.GET.get('name')
return HttpResponse('arg%s,%s'%(arg,name))
错误视图
视图就是python中的函数,视图一般被定义在"应用/views.py"文件中,此例中为"booktest/views.py"文件。视图必须返回一个HttpResponse对象或子对象作为响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误等。
视图的第一个参数必须为HttpRequest实例,还可能包含下参数如:
- 通过正则表达式组获得的关键字参数。
- 通过正则表达式组获取的位置参数。
内置错误视图
Django内置处理HTTP错误的视图,主要错误及视图包括:
- 404错误:page not found视图
- 500错误:server error视图
如果想看到错误视图而不是调试信息,需要修改test3/setting.py文件的DEBUG项。
DEBUG = False
ALLOWED_HOSTS = ['*', ]
404错误及视图
将请求地址进行url匹配后,没有找到匹配的正则表达式,则调用404视图,这个视图会调用404.html的模板进行渲染。视图传递变量request_path给模板,表示导致错误的URL。
1)在templates中创建404.html。
2)定义代码如下:
<html>
<head>
<title></title>
</head>
<body>
找不到了
<hr/>
{{request_path}}
</body>
</html>
3)在浏览器中输入如下网址:
http://127.0.0.1:8000/test/
4)运行效果如下图:
500错误及视图
在视图中代码运行报错会发生500错误,调用内置错误视图,使用templates/500.html模板渲染。
视图处理过程如下图:
HttpReqeust对象
服务器接收到http协议的请求后,会根据报文创建HttpRequest对象,这个对象不需要我们创建,直接使用服务器构造好的对象就可以。视图的第一个参数必须是HttpRequest对象,在django.http模块中定义了HttpRequest对象的API。
属性
下面除非特别说明,属性都是只读的。
- path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
- method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'。
- 在浏览器中给出地址发出请求采用get方式,如超链接。
- 在浏览器中点击表单的提交按钮发起请求,如果表单的method设置为post则为post请求。
- encoding:一个字符串,表示提交的数据的编码方式。
- 如果为None则表示使用浏览器的默认设置,一般为utf-8。
- 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
- GET:QueryDict类型对象,类似于字典,包含get请求方式的所有参数。
- POST:QueryDict类型对象,类似于字典,包含post请求方式的所有参数。
- FILES:一个类似于字典的对象,包含所有的上传文件。
- COOKIES:一个标准的Python字典,包含所有的cookie,键和值都为字符串。
- session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django 启用会话的支持时才可用,详细内容见"状态保持"。
- 运行服务器,在浏览器中浏览首页,可以在浏览器“开发者工具”中看到请求信息如下图:
示例
接下来演示属性path、method、encoding,对于GET、POST、FILES、COOKIES、session后面会有详细讲解。
path、encoding
1)打开booktest/views.py文件,代码如下:
print ('%s,%s'%(request.path,request.encoding))
method
1)打开booktest/views.py文件,编写视图method_show,代码如下:
return HttpResponse(request.method)
3)修改templates/booktest/下创建index.html文件,添加代码如下:
<html>
<head>
<title>首页</title>
</head>
<body>
...
...
2.request对象的method属性:<br/>
<a href='/arg22/'>get方式</a><br/>
<form method="post" action="/arg22/">
<input type="submit" value="post方式">
</form>
<br/>
</body>
</html>
4)打开浏览器,输入如下网址:
http://127.0.0.1:8000/
5)浏览效果如下图:
6)点击链接,转到method_show,浏览效果如下图:
- 回到method_test页面,点击按钮,转到method_post,浏览效果如下图,报错了。
8)打开test3/settings.py文件,将MIDDLEWARE_CLASSES项的csrf注释。
9)回到浏览器中刷新,浏览效果如下图,点击“继续”按钮。
10)最终浏览效果如下图:
QueryDict对象
- 定义在django.http.QueryDict
- HttpRequest对象的属性GET、POST都是QueryDict类型的对象
- 与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况
- 方法get():根据键获取值
- 如果一个键同时拥有多个值将获取最后一个值
- 如果键不存在则返回None值,可以设置默认值进行后续处理
dict.get('键',默认值)
可简写为
dict['键']
- 方法getlist():根据键获取值,值以列表返回,可以获取指定键的所有值
- 如果键不存在则返回空列表[],可以设置默认值进行后续处理
dict.getlist('键',默认值)
GetandPost属性
GET属性
请求格式:在请求地址结尾使用?,之后以"键=值"的格式拼接,多个键值对之间以&连接。
例:网址如下
http://127.0.0.1/?a=10&b=20&c=python
其中的请求参数为:
a=10&b=20&c=python
- 分析请求参数,键为'a'、'b'、'c',值为'10'、'20'、'python'。
- 在Django中可以使用HttpRequest对象的GET属性获得get方方式请求的参数。
- GET属性是一个QueryDict类型的对象,键和值都是字符串类型。
- 键是开发人员在编写代码时确定下来的。
- 值是根据数据生成的。
Post属性
get方式:<br/>
<a href="/arg66/?username=1&passwd=2">get方式提交数据</a><br/>
post方式:<br/>
<form method="post" action="/arg/">
账号:<input type="text" name="username"><br/>
密码:<input type="password" name="passwd"><br/>
<input type="submit" value="提交">
</form>
username = request.POST.get('username')
passwd = request.POST.get('passwd')