1、 新建虚拟环境
在该文件夹(learn)内,新建一个虚拟环境,learn\python-mvenvll_env
2、 激活虚拟环境
进入虚拟环境文件夹ll_env中的Scripts文件夹,利用命令行,激活虚拟环境ll_env\Scripts\activate
3、 安装Django
(如有,则忽略。建议在pycharm-settings里面projectinterpreter选择到一个有装满完整相关package的项目)
安装django.在learn文件夹内。learn\pipinstallDjango
4、 新建项目
在learn文件夹内新建一个项目(learning_log),\learn>django-adminstartprojectlearning_log
4.1、 项目(如project03)目录层级说明
Manage.py
一个命令行工具,可以使我们用多种方式对django项目进行交互。不修改,只用于使用。
project目录:
__init__.py
一个空文件,它告诉python这个目录应该被看作一个python包
Settings.py
项目的配置文件
Urls.py
项目的url声明
Wsgi.py
项目与wsgi兼容的web服务器入口
5、 启动服务器,测试是否建立成功
启动服务器,查看项目:pythonmanage.pyrunserver8080(将端口号改为8080,默认为8000)
6、 创建应用
创建应用:\项目文件夹>pythonmanage.pystartapp
6.1、 应用(如app0301)目录说明
admin.py进行站点配置
models.py创建模型
views.py创建视图
7、 激活应用(在settings.py)
在setting.py下加入,
INSTALLED_APPS=(
--snip--
'django.contrib.staticfiles',
#我的应用程序
'应用名称',)
8、 创建模型(在settings.py)
定义模型:
9、 配置数据库(在settings.py)
Django默认使用SQLite数据库,在settings.py文件中通过DATABASES选项进行数据库配置
9.1、 配置MySQL
Python3.x中安装的是PyMySQL,(在项目的文件夹下)__init__.py文件中写入两行代码
import pymysql |
以数据库hxiaoli-03为例进行示范:对settings.py中的DATABASES进行设置
DATABASES={
'default':{
'ENGINE':'django.db.backends.mysql',
'NAME':'hxiaoli03',
'USER':'root',
'PASSWORD':'python098',
'HOST':'localhost',#数据库服务器IP地址
'PORT':'3306',
}
}
10、 在mysql中创建刚配置的数据库
例如,hxiaoli03
use mysql
create database hxiaoli03 ;
11、 定义语言和时间(在settings.py)
from django.utils.translation import gettext_lazy as _ # 要引入这个包 |
12、 创建超级用户
创建超级用户:\learn\learning_log>python manage.py createsuperuser
13、 定义模型
定义模型概述:models.py下定义模型(有一个数据表,就对应有一个模型),模型就是一个类,类的属性,就是数据表的一个字段。
from django.db import models # 模型类要继承models.Model类,Model是django 中定义了模型基本功能的类 ) #定义外键的时候需要加上 on_delete=;否则,模型迁移时会出现错误 |
说明:不需要定义主键,在生成时自动添加,并且值为自动增加
13.1、关于isDelete
使用了这个标记,就等于增加了回收站功能,所以数据的删除,就不是直接删除,而是放入回收站。所谓放入回收站,就是将artilce的这个默认为0的标记改成1:
article.IsDelete=1;
article.update();
只有真正的彻底删除才需要 article.delete()
总之,这个问题是一个设计问题,不是技术问题;我只能告诉我是怎么设计的,至于你是否应该这么设计,完全看你自己的自由,技术上不是强制或者必须的(比如你用99或者-1来表示删除;比如你把数据放到一个临时表中……)。你自己多测试,看看运行的结果,应该会明白的。
13.2、django admin下拉列表不显示值,显示为object的处理
要加上:
def __str__(self):
return self.g_name
# 返回的形式 ,而且不能是__unicode__(self):
13.3、定义外键的时候需要加上 on_delete=;
定义外键的时候需要加上 on_delete=;否则,模型迁移时会出现错误
TypeError: init() missing 1 required positional argument: ‘on_delete’
on_delete各个参数的含义如下:
由于多对多(ManyToManyField)没有 on_delete 参数,所以以上只针对外键(ForeignKey)和一对一(OneToOneField)
14、 迁移模型
在manage.py所在文件夹内
\learn\learning_log>pythonmanage.pymakemigrations应用名称
\learn\learning_log>pythonmanage.pymigrate
15、 向管理网站中注册模型
from django.contrib import admin |
16、 查询数据:
(l_env)F:\01-sunck\project>pythonmanage.pyshell
Python3.7.4(default,Aug92019,18:34:13)[MSCv.191564bit(AMD64)]onwin32
Type"help","copyright","credits"or"license"formoreinformation.
(InteractiveConsole)
>>>fromapp1.modelsimportGrades
>>>fromdjango.utilsimporttimezone
>>>fromdatetimeimport*
>>>Grades.objects.all()
<QuerySet[]>
添加数据的本质:创建一个模型类的对象实例
17、 在数据库中生成数据表
17.1、生成迁移文件
执行pythonmanage.py makemigrations在migrations目录下生成一个迁移文件,此时数据库中还没有生成数据表
17.2、执行迁移
执行pythonmanage.py migrate相当于执行MySQL语句创建了数据表
18、 测试数据操作
进入到pythonshell,执行python manage.py shell
18.1、查询所有数据
类名.objects.all()
示例:Grades.objects.all()
引入包,并查询所有数据
In [1]: from app0301.models import Grades,Students In [2]: from django.utils import timezone In [3]: from datetime import * In [4]: Grades.objects.all() Out[4]: <QuerySet []> # 未添加数据时为空 |
18.2、添加数据
本质:创建一个模型类的对象实例
示例:CMD窗口下:
grade1=Grades()
grade1.gname="python04"
grade1.gdate=datetime(year=2017,month=7,day=17)
grade1.ggirlnum=3
grade1.gboynum=70
grade1.save()
18.3、查看某个对象
类名.objects(pk=索引号)
示例:
Grades.objects.get(pk=2)
Grades.objects.all()
18.4、修改某个数据
模型对象属性=新值
示例:
grade2.gboynum=60
grade2.save()
18.5、删除数据
模型对象.delete()
grade2.delete()
注意:这是物理删除,数据库中的相应数据被永久删除
18.6、关联对象
示例:
stu=Students()
stu.sname="XueYanmei"
stu.sgender=False
stu.sage=20
stu.scontend="IamXueYanmei"
stu.sgrade=grade1
stu.save()
需求:猎取python04班级的所有学生
对象名.关联的类名小写_set.all()
示例:grade1.students_set.all()
需求:创建曾志伟,属于python04班级
示例:
stu3=grade1.students_set.create(sname=u'ZhenZhiwei',sgender=True,scontend=u"IamZhenZhiwei",sage=45)
注意:这样创建的数据直接被添加到了数据库当中。
启动服务器:
格式:pythonmanage.pyrunserverip:port
注意:ip可以不写,不写代表本机ip
端口号默认是8000
pythonmanage.pyrunserver
说明:
这是一个纯python编写的轻量级web服务器,仅仅在开发测试中使用这个
19、 Admin站点管理:
概述:内容发布:负责添加,修改,删除内容的公告访问
19.1、自定义管理页面:
19.1.1、 属性说明
19.1.1.1、 列表页属性与添加,修改页属性
#列表页属性 list_display=[]#显示字段设置 list_filter=[]#过滤字段设置 search_fields=[]#搜索字段设置 list_per_page=[]#分页设置 | #添加,修改页属性 fields=[]#规定属性的先后顺序 fieldsets=[]#给属性分组注意:fields与fieldsets不能同时使用 |
属性示例: from django.contrib import admin # 该列表页管理类一定要写在admin.site.register(Grades,GradesAdmin),不然会提示“GradesAdmin”还未被定义。先定义后使用。Admin.py里面都要遵循先创建类再使用的原则,不然会提示不存在。 ----- StudentAdmin就不列出了----- |
19.1.1.2、 列表页属性效果图:
19.1.1.3、 Fields效果图:
19.1.1.4、 Fieldsets效果图
19.1.2、 关联对象:(在创建一个班级时可以直接添加几个学生)
需求:在创建一个班级时可以直接添加几个学生
class StudentsInfo(admin.TabularInline):#可选参数admin.StackedInline |
19.1.3、 布尔值显示问题示例:
class StudentsAdmin(admin.ModelAdmin): |
**:要先定义方法再进行传值
19.1.4、 执行动作按钮位置:
class StudentsAdmin(admin.ModelAdmin): …snip… |
19.2、使用装饰器完成注册:
@admin.register(Students)
classStudentsAdmin(admin.ModelAdmin):
defgender(self):
...snip...
actions_on_top=False
actions_on_bottom=True
视图的基本使用
概述:
在Django中,视图是对web请求进行回应
视图就是一个python函数,在views.py文件中定义。
定义视图:
示例:在myApp\views.py中写入
fromdjango.shortcutsimportrender
#Createyourviewshere.
fromdjango.httpimportHttpResponse
defindex(request):
returnHttpResponse("Sunckisagoodman")
配置url:方法一:path方法:
修改project目录下的urls.py文件:
fromdjango.contribimportadmin
fromdjango.urlsimportpath,include
urlpatterns=[
path('admin/',admin.site.urls),
path('',include('myApp.urls')),
]
在myApp应用目录下创建urls.py文件:
fromdjango.urlsimportpath,include
from.importviews
urlpatterns=[
path('',views.index),
]
配置url:方法二:url方法:
修改project目录下的urls.py文件:
fromdjango.contribimportadmin
fromdjango.conf.urlsimporturl,include
urlpatterns=[
url(r'^admin/',admin.site.urls),
url(r'^',include('myApp.urls')),
]
在myApp应用目录下创建urls.py文件:
fromdjango.conf.urlsimporturl
from.importviews
urlpatterns=[
url(r'^$',views.index),
]
模板的基本使用:
概述:模板是HTML页面,可以根据视图中传递过来的数据进行填充
创建模板:
创建templates目录,在目录下创建对应项目的模板目录(project/templates/myApp)
配置模板路径:
修改settings.py文件下的TEMPLATES下的'DIRS'为'DIRS':[os.path.join(BASE_DIR,'templates')],
定义grades.html与students.html模板:
在templates\myApp\目录下创建grades.html与students.html模板文件
模板语法:
{{输出值,可以是变量,也可以是对象,属性}}
{%执行代码段%}
http://127.0.0.1:8000/grades
写grades.html模板:
<!doctypehtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metaname="viewport"
content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
<metahttp-equiv="X-UA-Compatible"content="ie=edge">
<title>班级信息</title>
</head>
<body>
<h1>班级信息列表</h1>
<ul>
<!--[python04,python05,python06]-->
{%forgradeingrades%}
<li>
<ahref="#">{{grade.gname}}</a>
</li>
{%endfor%}
</ul>
</body>
</html>
定义视图:myApp\views.py
from.modelsimportGrades
defgrades(request):
#去模板里取数据
gradesList=Grades.objects.all()
#将数据传递给模板,模板再渲染页面,将渲染好的页面返回给浏览器
returnrender(request,'myApp/grades.html',{"grades":gradesList})
配置url:myApp\urls.py
urlpatterns=[
url(r'^$',views.index),
url(r'^(\d+)/(\d+)$',views.detail),
url(r'^grades/',views.grades)
]
http://127.0.0.1:8000/students
写students.html模板
<!doctypehtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metaname="viewport"
content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
<metahttp-equiv="X-UA-Compatible"content="ie=edge">
<title>学生页面</title>
</head>
<body>
<h1>学生信息列表</h1>
<ul>
{%forstudentinstudents%}
<li>
{{student.sname}}--{{student.scontend}}
</li>
{%endfor%}
</ul>
</body>
</html>
定义视图:myApp\views.py
from.modelsimportStudents
defstudents(request):
studentsList=Students.objects.all()
returnrender(request,'myApp/students.html',{"students":studentsList})
配置url:myApp\urls.py
urlpatterns=[
url(r'^$',views.index),
url(r'^(\d+)/(\d+)$',views.detail),
url(r'^grades/',views.grades),
url(r'^students/',views.students),
]
需求:点击班级,显示对应班级的学生名字
运行不正常https://www.bilibili.com/video/av17879644/?p=12
Django流程梳理
创建工程:执行django-adminstartproject工程名
创建项目:执行pythonmanage.pystartapp项目名称
激活项目:修改settings.py中的INSTALLED_APPS
配置数据库:
修改__init__.py文件
修改settings.py文件中的DATABASES
创建模型类:在项目目录下的models.py文件中创建
生成迁移文件:执行pythonmanage.pymakemigrations
执行迁移:执行pythonmanage.pymigrate
配置站点:略
创建模板目录/项目模板目录
在settings.py中的TEMPLATES添加templates路径
在工程目录下(project)修改urls.py
在项目目录下创建urls.py
使用他人Django代码需要的简易修改:
1.在settings.py中修改数据库名
2.在settings.py中修改数据库密码
3.删除由内向外文件(在对应目录里鼠标右键删除)
4.在数据库中创建对应第一步的数据库(自己在SQL中创建)
5.执行生成迁移文件
6.执行迁移
7.启动服务
8.浏览器测试
Django模型
Django对各种数据库提供了很好的支持,Django为这些数据库提供了统一的调用API
我们可以根据不同的业务需求选择不同的数据库。
配置数据库
修改工程目录下的__init__.py文件
importpymysql
pymysql.install_ad_MySQLdb()
修改settings.py文件中的DATABASES
开发流程
配置数据库
定义模型类:一个模型都在数据库中对应一张数据库表
生成迁移文件
执行迁移生成数据表
使用模型类进行增删改查
ORM
概述:对象-关系-映射
任务:
根据对象的类型生成表结构
将对象,列表的操作转换成SQL语句
将SQL语句查询到的结果转换为对象,列表
优点:
极大的减轻了开发人员的工作量,不需要面对因数据库的变更而修改代码的问题
定义模型
创建模型类
元选项
在模型类中定义Meta类,用于设置元信息
示例:
classMeta:
db_table="students"
ordering=['id']
db_table
定义数据表名,推荐用小写字母,数据表名默认为项目名小写_类名小写
ordering
对象的默认排序字段,获取对象的列表时使用
示例:
ordering['id']id按升序排列
ordering['-id']id按降序排列
注意:排序会增加数据库开销
模型成员
类属性
隐藏类属性objects:也是模型类的一个管理器
是Manager类型的一个对象,作用是与数据库进行交互。用mysqlworkbench或者mysql命令行窗口修改,最后一次修改时间没有体现。但是如果用pycharmshell修改就会体现。如果想要体现当前的系统时间的话,必须在settings里面设置,TIME_ZONE='Asia/Shanghai',USE_TZ=False。
当定义模型类时没有指定管理器,则Django为模型创建一个名为objects的管理器
自定义管理器示例:
定义stuObj管理器:(作用不大)
stuObj=models.Manager()#在Students类里面,是大写的Manage,不是小写的manage
当为模型指定模型管理器,Django就不再为模型类生成objects模型管理器了。即,Students.objects.get(pk=1)就会出错。
自定义管理器Manager类
模型管理器是Django的模型进行与数据库交互的窗口,一个模型可以有多个模型管理器
作用:
1. 向管理器类中添加额外的方法
2. 修改管理器返回的原始查询集。(什么是查询集:比如Student.objects.all(),但是原始查询集是把数据库里面所有的信息都返回回来,而修改原始查询集就可以进行一定的过滤。)通常会重写get_queryset()方法
代码示例:
classStudentsManager(models.Manager):
defget_queryset(self):
returnsuper(StudentsManger,self).get_queryset().filter(isDelete=False)
classStudents(model.Moder):
#自定义模型管理器
#当自定义模型管理器,objects就不存在了
stuObj=models.Manger()
stuObj2=StudentsManager()
创建对象
目的:向数据库中添加数据
当创建对象时,django不会对数据库进行读写操作,当调用save()方法时才与数据库交互,将对象保存在数据库表中。
注意:__init__方法已经在父类models.Model中使用,在自定义的模型中无法使用。
方法:
在模型类中增加一个类方法,示例如下:
#定义一个类方法创建对象
@classmethod#表示类方法
defcreateStudents(cls,name,age,gender,content,grade,lasttime,isdelete=False):#cls代表前面的ClassStudents,假如前面没有假如@classmethod,则括号里面写cls
stu=cls(sname=name,sage=age,sgender=gender,scontend=content,sgrade=grade,lastTime=lasttime,isDelete=isdelete)#传值
returnstu
在自定义管理器中添加一个方法,示例如下:
classStudentsManager(models.Manager):
defget_queryset(self):
returnsuper(StudentsManager,self).get_queryset().filter(isDelete=False)
defcreateStudent(self,name,age,gender,contend,grade,lastT,createT,isD=False):
stu=self.model()
#print(type(grade))
stu.sname=name
stu.sage=age
stu.sgender=gender
stu.scontend=contend
stu.sgrade=grade
stu.lastTime=lastT
stu.createTime=createT
returnstu
模型查询
概述
查询集表示从数据库获取的对象的集合
查询集可以有多个过滤器
过滤器就是一个函数,基于所给的参数限制查询集结果
从SQL角度来说,查询集和select语句等价,过滤器就像where条件
查询集
在管理器上调用过滤器方法返回查询集
查询集经过过滤器筛选后返回新的查询集,所以可以写成链式调用
惰性执行
创建查询集不会带来任何数据库的访问,直到调用数据库时,才会访问数据
直接访问数据的情况:
迭代
序列化
与if合用
返回查询集的方法称为过滤器
all():返回查询集中的所有数据
filter():保留符合条件的数据
filter(键=值)
filter(键=值,键=值)
filter(键=值).filter(键=值)且的关系
exclude():过滤掉符合条件的
order_by():排序
values():一条数据就是一个字典,返回一个列表
get()
返回一个满足条件的对象
注意:
如果没有找到符合条件的对象,会引发模型类.DoesNotExist异常
如果找到多个对象,会引发模型类MultipleObjectsReturned异常
count():返回查询集中对象的个数
first():返回查询集中第一个对象
last():返回查询集中最后一个对象
exits():判断查询集中是否有数据,如果有数据返回True,否则返回False.
限制查询集
查询集返回列表,可以使用下标的方法进行限制,等同于sql中的limit语句
注意:下标不能是负数
示例:studentsList=Students.stuObj2.all()[0:5]
查询集的缓存
概述:
每个查询集都包含一个缓存,来最小化对数据库的访问
在新建的查询集中,缓存首次为空,第一次对查询集求值,会发生数据缓存,Django会将查询出来的数据做一个缓存,并返回查询结果。
以后的查询直接使用查询集的缓存
字段查询
概述
实现了sql中的where语句,作为方法filter(),exclude(),get()的参数
语法:属性名称__比较运算符=值
外键:属性名称_id
转义:类似sql中的like语句
like有关情况看我哥他%是为了匹配点位,匹配数据中的%使用(wherelike"\%")
filter(sname__contains="%")
比较运算符
exact:判断,大小写敏感
filter(isDelete=False)
contains:是否包含,大小写敏感
studentsList=Students.stuObj2.filter(sname__contains="孙")
startswith,endswith:以value开头或结尾,大小写敏感
以上四个在前面加上i,就表示不区分大小写iexact,icontains,istartswith,iendswith
isnull,isnotnull
是否为空
filter(sname__isnull=False)
in:是否包含在范围内
gt大于,gte大于等于,lt小于,lte小于等于
year,month,day,week_day,hour,minute,second
studentsList=Students.stuObj2.filter(lastTime__year=2017)
跨关联查询
处理join查询
语法:
模型类名__属性名__比较运算符
#描述中带有‘薛延美’这三个字的数据是属于哪个班级的
grade=Grades.objects.filter(students__scontend__contains='薛延美')
print(grade)
查询快捷pk代表的主键
聚合函数
使用aggregate函数返回聚合函数的值
Avg
Count
Max
maxAge=Student.stuObj2.aggregate(Max('sage'))
maxAge为最大的sage。
Min
Sum
F对象
可以使用模型的A属性与B属性进行比较
fromdjango.db.modelsimportF,Q
defgrades1(request):
g=Grades.objects.filter(ggirlnum__gt=F('gboynum'))
print(g)
#[<Grades:python02>,<Grades:python03>]
returnHttpResponse("OOOOOOOo")
支持F对象的算术运算
g=Grades.objects.filter(ggirlnum__gt=F('gboynum')+20)
Q对象
概述:过滤器的方法的关键字参数,条件为And模式
需求:进行or查询
解决:使用Q对象
defstudents4(request):
studentsList=Students.stuObj2.filter(Q(pk__lte=3)|Q(sage__gt=50))
returnrender(request,'myApp/students.html',{"students":studentsList})
只有一个Q对象的时候,就是用于正常匹配条件
studentsList=Students.stuObj2.filter(~Q(pk__lte=3))
~Q是取反
定义属性
概述:
django根据属性的类型确定以下信息
当前选择的数据库支持字段的类型
渲染管理表单时使用的默认html控件
在管理站点最低限度的验证
django会为表增加自动增长的主键列,每个模型只能有一个主键列,如
果使用选项设置某属性为主键列后,则django不会再生成默认的主键列
属性命名限制
遵循标识符规则,且变量不能与Python保留字相同
由于django的查询方式,不允许使用连续的下划线
库
定义属性时,需要字段类型,字段类型被定义在django.db.models.fields目录下,
为了方便使用,被导入到django.db.models中
使用方式
导入:fromdjango.dbimportmodels
通过models.Field创建字段类型的对象,赋值给属性
逻辑删除
对于重要类型都做逻辑删除,不做物理删除,实现方法是定义idDelete属性,
类型为BooleanField,默认值为False
字段类型
autoField
一个根据实际ID自动增长的IntegerField,通常不指定,
如果不指定,一个主键字段将自动添加到模型中
CharField(max_length=字符长度)
字符串,默认的表彰样式是TextInput
TextField
大文本字段,一般超过4000时使用,默认的表单控件是Textarea
IntegerField
整数
DecimalField(max_digits=None,decimal_places=None)
使用Python的Decimal实例表示的十进制浮点数
参数说明
DecimalField.max_digits
位数总数
DecimalField.decimal_places
小数点后的数字位置
FloatField
使用Python的float实例来表示的浮点数
BooleanField
True/False字段,此字段的默认表彰控制是CheckboxInput
NullBooleanField
支持Null,True,False三种值
DateField([auto_now=False,auto_now_add=False])
使用Python的datetime.date实例表示的日期
参数说明:
DateField.auto_now
每次保存对象时,自动设置该字段为当前时间,用于“最后一次修改”
的时间戳,它总是使用当前日期,默认为False
DateField.auto_now_add
当前对象第一次被创建时自动设置当前时间,用于创建的时间戳,
它总是使用当前日期,默认为False
说明
该字段默认对应的表单控件是一个TextInput.在管理员站点添加了一个
JavaScript写的日历控件,和一个“Today”的快捷按钮,包含了一个额外
的invalid_date错误消息键
注意
auto_now_add,auto_now,anddefault这些设置是相互排斥的,他们之间
的任何组合将会发生错误的结果
TimeField
使用Python的datetime.time实例表示的时间,参数同DateField
DateTimeField
使用Python的datetime
datetime实例表示的日期和时间,参数同DateField
FileField
一个上传文件的字段
ImageField
继承了FileField的所有属性和方法,但对上传的对象进行校验,
确保它是一个有效的image
字段选项
概述
通过字段选项,可以实现对字段的约束
在字段对象中通过关键字参数指定
null
如果为True,Django将空值以NULL存储在数据库中,默认值为False
blanke
如果为True,则该字段允许为空白,默认值为False
注意
null是数据库范畴的概念,blank是表彰验证范畴的概念
db_column
字段的名称,如果未指定,则使用属性的名称
db_index
若值为True,则在表中会为此字段创建索引
default
默认值
primary_key
若为True,则该字段会成为模型的主键字段
unique
如果为True,这个字段在表中必须有唯一值
关系
分类
ForeignKey:一对多,将字段定义在多的端中
ManyToManyField:多对多,将字段定义在两端中
OneToOneField:一对一,将字段定义在任意一端中
用一访问多
格式
对象.模型类小写_set
示例
grade.students_set
用一访问一
格式
对象.模型类小写
示例
grade.studnets
访问id
格式
对象.属性_id
示例
student.sgrade_id
视图
概述:
作用:视图接收web请求,并响应web请求
本质:视图就是python中的一个函数
响应:
响应过程:
用户在浏览器中输入网址www.sunck.wang/sunck/index.html
---网址--->
django获取网址信息,去掉IP与端口号,网址变成:sunck/index.html
---虚拟路径与文件名--->
url管理器逐个匹配urlconf,记录视图函数
---视图函数名--->
视图管理,找到对应的视图去执行,返回结果给浏览器
---响应的数据--->
返回第一步:用户在浏览器中输入网址
网页
重定向
错误视图
404视图:找不到网页(url匹配不成功时返回)时返回
在templates目录下定义404.html
<!doctypehtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metaname="viewport"
content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
<metahttp-equiv="X-UA-Compatible"content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>页面丢失</h1>
<h2>{{request_path}}</h2>
</body>
</html>
request_path:导致错误的网址
配置settings.py
DEBUG
如果为True,永远不会调用404页面,需要调整为False才会显示
ALLOWED_HOSTS=['*']
500视图:在视图代码中出现错误(服务器代码错误)
400视图:错误出现在客户的操作
JSON数据
url配置
配置流程:
制定根级url配置文件
settings.py文件中的ROOT_URLCONF
ROOT_URLCONF='project.urls'
默认实现了
urlpatterns
一个url实例的列表
url对象
正则表达式
视图名称
名称
url匹配正则的注意事项
如果想要从url中获取一个值,需要对正则加小括号
匹配正则前方不需要加'/'
正则前需要加'r'表示字符串不转义
引入其他url配置
在应用中创建urls.py文件,定义本应用的url配置,在工程urls.py中使用include方法
project\urls.py
fromdjango.contribimportadmin
fromdjango.conf.urlsimporturl,include
urlpatterns=[
url(r'^admin/',admin.site.urls),
url(r'^',include('myApp.urls',namespace="myAPP")),
]
myApp\urls.py
fromdjango.urlsimportpath,include
fromdjango.conf.urlsimporturl
from.importviews
urlpatterns=[
url(r'^$',views.index,name="index"),
]
url的反向解析
概述:如果在视图,模板中使用了硬编码链接,在url配置发生改变时,动态生成链接的地址
解决:在使用链接时,通过url配置的名称,动态生成url地址
作用:使用url模板
视图函数
定义视图:
本质:一个函数
视图参数:
一个HttpRequest的实例
通过正则表达式获取的参数
位置:一般在views.py文件下定义
HttpRequest对象
概述:
服务器接收http请求后,会根据报文创建HttpRequest对象
视图的第一个参数就是HttpRequest对象
django创建的,之后调用视图时传递给视图
属性
path:请求的完整路径(不包括域名和端口)
method:表示请求的方式,常用的有GET,POST
encoding:表示浏览器提交的数据的编码方式,一般为utf-8
GET:类似于字典的对象,包含了get请求的所有参数
POST:类似于字典的对象,包含了post请求的所有参数
FILES:类似字典的对象,包含了所有上传的文件
COOKIES:字典,包含所有的cookie
session:类似字典的对象,表示当前会话
方法
is_ajax():如果是通过XMLHttpRequest发起的,返回True
QueryDict对象
request对象中的GET,POST都属于QueryDict对象
方法:
get():
根据键获取值,只能获取一个值
www.sunck.wang/abc?a=1&b=2&c=3
getlist()
将键的值以列表的形式返回
可以获取多个值
www.sunck.wang/abc?a=1&b=2&c=3
GET属性
获取浏览器传递过来数据
www.sunck.wang/abc?a=1&b=2&c=3
urls.py
url(r'^get1',views.get1),#结尾不能加$,否则无法匹配
views.py
defget1(request):
a=request.GET.get('a')
b=request.GET.get('b')
c=request.GET.get('c')
returnHttpResponse(a+""+b+""+c)
www.sunck.wang/abc?a=1&a=2&c=3
urls.py
url(r'^get2',views.get2),
views.py
defget2(request):
a=request.GET.getlist('a')
a1=a[0]
a2=a[1]
c=request.GET.get('c')
returnHttpResponse(a1+""+a2+""+c)
POST属性
使用表单模拟POST请求
关闭CSRF:project\project\settings.py
MIDDLEWARE=[
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
示例:
defshowregist(request):
returnrender(request,'myApp/regist.html',)
defregist(request):
name=request.POST.get("name")
gender=request.POST.get("gender")
age=request.POST.get("age")
hobby=request.POST.getlist("hobby")
print(name)
print(gender)
print(age)
print(hobby)
returnHttpResponse("regist")
路径:
url(r'^showregist/$',views.showregist),
url(r'^showregist/regist/$',views.regist),
页面:
<!doctypehtml>
<htmllang="en">
<head>
<metacharset="UTF-8">
<metaname="viewport"
content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
<metahttp-equiv="X-UA-Compatible"content="ie=edge">
<title>注册</title>
</head>
<body>
<formaction="regist/"method="post">
姓名:<inputtype="text"name="name"value=""/>
<hr>
性别:<inputtype="radio"name="gender"value="1">男<inputtype="radio"name="gender"value="0">女
<hr>
爱好:<inputtype="checkbox"name="hobby"value="power"/>权利<inputtype="checkbox"name="hobby"value="money">金钱<inputtype="checkbox"name="hobby"value="beauty">美女<inputtype="checkbox"name="hobby"value="Tesla">Tesla
<hr>
<inputtype="submit"value="注册">
</form>
</body>
</html>
HttpResponse对象
概述:
作用:给浏览器返回数据
HttpRequest对象是由Django创建的,HttpResponse对象是由程序员创建
用法:
不用模板,直接返回数据
语句示例:returnHttpResponse("Sunckisagoodman")
调用模板
使用render方法
原型:render(request,templateName[,context])
作用:结合数据和模板,返回一个完整的HTML页面
参数:
request:请求体对象
templateName:模板路径
context:传递给需要渲染在模板上的数据
属性
content:表示返回内容
charset:编码格式
status_code:响应状态码
200
304
404
400
content-type:指定输出的MIME类型
方法
init:使用页面内容实例化HttpResponse对象
write(content):以文件的形式写入
flush():以文件的形式输出缓冲区
set_cookie(key,value,maxAge=None,exprise=None)
delete_cookie(key):
删除cookie
如果删除一个不存在的cookie,就当什么都没发生
子类HttpResponseRedirect
功能:重定向,服务器端的跳转
简写
redirect(to)
to推荐使用反向解析
示例:
fromdjango.httpimportHttpResponseRedirect
fromdjango.shortcutsimportredirect
defredirect1(request):
#returnHttpResponseRedirect('/redirect2')
returnredirect('/redirect2')
defredirect2(request):
returnHttpResponse("我是重定向后的视图")
子类JsonResponse
返回Json数据,一般用于异步请求
__init__(self.data)
data字典
注意:Content-type类型为application/json
状态保持
http协议是无状态的,每次请求都是一次新的请求,它不记得之前的请求。
客户端与服务器的一次通信就是一次会话
实现状态的保持,在客户端或服务端存储有关会话的数据
存储的方式
cookie:所有数据存储在客户端,不要存储敏感的数据
session:所有的数据存储在服务端,在客户端用cookie存储session_id
状态保持的目的:
在一段时间内跟踪请求者的状态,可以实现跨页面访问当前的请求者的数据
注意:不同的请求者之间不会共享这个数据,与请求者一一对应
启用session:project\project\settings.py
INSTALLED_APPS'django.contrib.sessions',
MIDDLEWARE'django.contrib.sessions.middleware.SessionMiddleware',
使用session
启用session后,每个httpRequest对象都有一个session属性
get[key,default=None]根据键获取session值
clear()清空所有会话
flush()删除当前会话并删除会话的cookie
示例:
#session
defmain(request):
#取session
username=request.session.get('name','游客')
print(username)
returnrender(request,'myApp/main.html',{'username':username})
deflogin(request):
returnrender(request,'myApp/login.html')
defshowmain(request):
print("*****************")
username=request.POST.get('username')
#存储session
request.session['name']=username
returnredirect('/main/')
fromdjango.contrib.authimportlogout
defquit(request):
#清除session
logout(request)#方法1,推荐
#request.session.clear()#方法2
request.session.flush()#方法3
returnredirect('/main/')
设置session过期时间
set_expiry(value)
request.session.set_expiry(10)设置为10秒后过期
如果不设置,2个星期后过期
value设置为0代表关闭浏览器时过期
value设置为None代表设置永不过期,不推荐