Django基础篇
1.Django框架简介
1)MVC
核心思想:解耦
M:model模型,和数据库进行交互。
V:View,视图,产生html页面。
C:Controller,控制器,接收请求,进行处理,与M和V进行交互,返回应答。
2)MVC处理流程
浏览器提交数据,数据交给控制器C,通过模型M将数据保存进数据库,数据库将保存结果返回给模型M,模型M将结果发送给控制器C,控制器C通过视图V产生html页面,视图V将页面交给控制器C,控制器C将页面返回给浏览器。
3)Django简介
Django为MVT框架。
M:model,模型,和数据库进行交互
V:view,视图,接收请求,进行处理,与M和T进行交互,返回应答
T:template,模板,产生html页面
Django处理流程:
浏览器提交数据,数据交给视图V,通过模型M将数据保存进数据库,数据库将保存结果返回给模型M,模型M将结果发送给视图V,视图V通过模板T产生html页面,模板T将页面交给视图V,视图V将页面返回给浏览器。
4)虚拟环境
真实python环境的复制版本
在虚拟环境中使用的python是复制的python,安装python包也是安装在复制的python里面,但是除此之外,创建的文件等操作,是在整个系统中进行。
安装虚拟环境的命令:
1>sudo pip install virtualenv 安装虚拟环境
2>sudo pip install virtualenvwrapper 安装虚拟环境扩展包
3>编辑家目录下面的..bashrc文件,添加下面两行
export WORKON_HOME=$HOME/.virtualenvs
source/usr/local/bin/virtualenvwrapper.sh
4>使用source .bashrc使其生效
创建虚拟环境
mkvirtualenv 虚拟环境名
创建python3虚拟环境
mkvirtualenv -p python3 虚拟环境名
进入虚拟环境工作
workon 虚拟环境名
退出虚拟环境
deactivate
查看现有操作系统下的虚拟环境
workon后按两次tab键
删除虚拟环境
rmvirtualenv 虚拟环境名
查看虚拟环境安装了哪些包
pip list
pip freeze
虚拟环境下安装包
pip install 包名
虚拟环境中不要使用sudo pip install 包名这个命令
apt-get install 软件
pip install python 包名
5)项目创建
命令:django-admin startproject
项目名
创建一个项目__init__.py
说明该项目是一个python包settings.py
项目的配置文件urls.py
进行url路由的配置wsgi.py
web服务器和Django交互的入口manage.py
项目的管理文件
实际中,将一个项目分为不同的功能模块。在Django开发中,一个功能模块用一个django应用来实现。
创建应用的命令:python manage.py startapp 应用名
创建一个应用
应用下的文件目sudo录:__init__.py
说明目录是一个python模块models.py
写和数据库有关的内容tests.py
写测试代码的文件。views..py
定义处理函数,视图函数。接收请求,进行处理。admin.py
网站后台管理相关的文件migrations/__init__.py
模型类生成表,迁移文件存放的地方
建立应用和项目之间的联系,需要对应用进行注册。
修改settings.py中的INSTALLED_APPS进行配置,把应用名加进去。
2.Django基本使用
1)ORM框架
Object:对象,类
Relationship:关系,关系数据库中的表
Mapping:映射
类中的数据映射到数据库中表的数据
通过类和对象操作对应的数据表,不需要写sql语句。model.py
文件中设计和表对应的类,模型类
ORM另外一个作用:根据设计的类生成数据库中的表。
功能:
1>建立模型类和表之间的对应关系,允许我们通过面向对象的方式来操作数据库。
2>根据设计的模型类生成数据库中的表格
3>通过方便的配置据可以进行数据库的切换
2)模型类
model.py
中
from django.db import models
class 类名(models.Model):
btitle = models.CharField(max_length=20)
#图书名称,CharField说明是一个字符串,max_length指定字符串的最大长度
bpub_date = models.DateField()
#出版日期,DateField说明是一个日期类型
通过模型类生成表
1>生成迁移文件
python manage.py makemigrations
迁移文件是根据模型类生成的
2>执行迁移生成表
python manage.py migrate
根据迁移文件生成相应数据库的表
数据库的类型在settings.py中设置。
生成表明的默认格式: 应用名_模型类名小写
3)通过模型类操作数据表
进入项目shell的命令: python manage.py shell
创建类的实例,设置好属性后,使用对象名.save()将对象插入到数据表中。
b2 = 模型类名.objects.get(id=1)
将模型类名对应的数据表中的id为1 的数据赋给b2
4)模型关系和查询关系
一对多关系:在关系为多的类中建立一个关系属性
定义关系为多的类时:
关系属性名 = models.ForeignKey('关系为一的类名') # 外键
定义关系为多的类的实例时:
实例名.关系属性名 = 对应的关系为一的类的实例名
由一查多
一类的实例名.多类名(小写)_set.all()
由多查一
多类的实例名.关系属性名
查询表里面的所有内容:
类名.objects.all()
5)后台管理
admin.py文件中
1>本地化
语言和时区的本地化
修改setting.py文件:LANGUAGE_CODE及TIME_ZONE
2>创建管理员
命令:
python manage.py createsuperuser
3>注册模型类
在应用下的admin.py中注册模型类。
告诉django框架根据注册的模型类来生成对应表管理页面。
admin.site.register(模型类的类名) #记得导入模型类
4>自定义管理页面
admin.py文件中定义一个自定义模型管理类
class 类名(admin.ModelAdmin):
list_display = [需要显示的属性1,需要显示的属性2,…] #设置管理系统需要
显示的属性
将这个类添加到register函数中
6)视图view
Django中,通过浏览器去请求一个页面时,使用视图函数来处理这个请求,视图函数处理之后,要给浏览器返回页面内容。
视图函数使用
1>定义视图
view.py
文件中
def 函数名(request):
#进行处理,和M、T进行交互
return HttpResponse(返回的内容)
视图函数必须有request参数
2>进行url配置
目的:建立url地址和视图的对应关系,即路由
应用文件夹中,建立urls.py
文件,通过url函数设置url路由配置项
并且将应用文件中的urls加到项目的urls文件中
url配置项都定义在一个叫做urlpatterns的列表中,每一个配置项都会调用url函数,第一个参数是正则表达式,第二个参数是对应的处理动作,然后url字符串进行正则匹配,匹配成功则执行第二个参数对应的动作,对应的动作可以是一个视图函数的名字,也可以是包含一个应用的urls.py
文件。
配置url时,语法格式:
a url(正则表达式,视图函数名)
b url(正则表达式,include(应用中的urls文件))
注意:进行url配置的时候:a 严格匹配开头和结尾;b 匹配时,在项目的urls文件中匹配到之后,会把匹配到的部分去掉,用剩余部分到应用的urls文件中进行继续匹配。
7)模板 template
模板不仅仅是一个html文件
模板的使用
1>创建模板文件夹
项目目录下创建一个新文件夹
2>配置模板目录
在settings.py文件中,找到TEMPLATES,在DIRS参数后面设置模板的地址
setting.py文件中有一个BASE_DIR是项目的绝对路径,设置路径时可以将该绝对路径与templates拼起来
3>使用模板文件
a 加载模板文件
去模板目录下面获取html文件的内容,得到一个模板对象
from django.template import loader
loader.get_template(路径)
b 定义模板上下文
向模板文件传递数据
from django.template import RequestContext
RequestContext(request,[])
c 模板渲染
得到一个标准的html内容
from django.template import loader
return res_html = temp.render(context)
实际开发中,使用模板文件的过程:
return render(request, 路径, 字典(可空))
字典中的内容可以替换模板文件中的内容,模板中可替换的内容格式为 双花括号 {{要替换的内容}},字典中,以要替换的内容作为关键字。
html中循环
{% for book in books %}
<li>{{book.btitle}}</li>
{% endfor %}
3.Model属性及后端配置
1)数据库配置
setting.py文件中,对DATABASES参数内容进行修改,
ENGINE加入mysql,
NAME数据库名字,
USER输入用户名,
PASSWORD数据库密码
HOST 指定mysql数据库所在电脑ip,
PORT数据库端口号
项目中的__init__.py
文件中,加入:
import pymysql
pymysql.install_as_MySQLdb()
注意:return HttpResponse
时,页面跳转到新页面return HttpResponseRedirect(‘地址')
页面会跳转到指定页面 即 重定向
页面重定向:服务器不返回页面,而是告诉浏览器再去请求其他的url地址
2)字段属性和选项
1>模型类属性命名限制:
a 不能是python的保留关键字
b 不允许使用连续的下划线,这是由django的查询方式决定的
c 定义属性时需要指定字段类型,通过字段类型的参数指定选项,语法如下:
属性名=models.字段类型(选项)
2>字段类型
需要导入django.db的models包
对比:null是数据库范畴的概念,blank是后台管理页面表单验证范畴的。
经验:当修改模型类之后,如果添加的选项不影响表的结构,则不需要重新做迁移,商品的选项中default和blank不影响表结构。
3)查询
通过模型类.objects属性
可以调用如下函数,实现对模型类对应的数据表的查询。get函数
:返回表中满足条件的一条且只能有一条数据,返回值是一个对象all函数
:返回模型类对应表格中的所有数据,返回值是QuerySetfilter函数
:返回满足条件的数据 模型类属性名_条件名 = 值,返回值是QuerySetexclude函数
:返回不满足条件的数据,返回值是QuerySetorder_by函数
:对查询结果进行排序 默认从小到大,返回值是QuerySet
模糊查询模型类名.object.filter(属性名__contains=‘信息’)
# 指定属性名中包含“信息“的数据endswith
查询以指定信息结尾的数据 startswith 以指定信息开头的数据
空查询:isnull filter(属性名__isnull=False)
不为空的数据
范围查询:in filter(属性名__in = [])
在列表中的数据
比较查询:gt、lt、gte、lte filter(属性名__gt=3) 指定属性大于三的数据
日期查询:
a 年查询:filter(属性__year=年份)
b 具体日期:filter(属性__gt=date(1980,1,1))
指定属性1980年1月1日后的数据
exclude查询:exclude(属性名=信息)
指定属性不为指定信息的数据
4)Q对象
作用:用于查询时条件之间的逻辑关系。not and or,可以对Q对象进行&|~操作
先导入Q
from django.db.models import Q
模型类名.objects.filter(Q(查询条件1) Q(查询条件2))
两个Q对象之间加入&|~表示逻辑关系。
5)F对象
作用:用于类属性之间的比较
先导入
from django.db.models import F
6)聚合函数
sum count avg max min
Django中使用aggregate函数
来实现聚合,返回值是一个字典
导入
from Django.db.models import Sum,Count,Max,Min,Avg
Django中也有count函数,返回值是一个数字
注意:对一个QuerySet实例对象,可以继续调用上面的所有函数。
7)查询集
特性:
1>惰性查询:只有在实际使用查询集中的数据的时候才会发生对数据库的真正查询。
2>缓存:当使用的是同一个查询集时,第一次的时候会发生实际数据库的查询,然后把结果缓存起来,之后再使用这个查询集时,使用的是缓存中的结果。
限制查询集:
可以对一个查询集进行取下标或者切片操作来限制查询集的结果。
对一个查询集进行切片操作会产生一个新的查询集,下标不允许为负数。
取出查询集第一条数据的两种方式:
b[0]
b[0: 1].get()
exists函数可以判断一个查询集中是否有数据。
4.模型关系及相关操作
1)模型类关系
一对多关系:models.ForeignKey()
定义在多的类中
多对多关系:models.ManyToManyField()
定义在哪个类中都可以
一对一关系:models.OneToOneField
定义在哪个类中都可以
2)关联查询(一对多)
1>之前
由一查多
一类的实例名.多类名(小写)_set.all()
由多查一
多类的实例名.关系属性名
2>通过模型类实现关联查询
一类名.objects.filter(多类名__多类属性名__查询条件)
多类名.objects.filter(关系属性名__一类属性及查询条件)
经验:要查哪个表中的数据,就需要通过哪个类来查;写关联查询条件的时候,如果类中没有关系属性,条件需要写对应类的名字,如果类中有关系属性,查询条件直接写关系属性。
3)插入删除
对象的save和delete函数进行插入和删除
4)自关联
自关联是特殊的一对多,一对多的关系都在表中
使用子对象名.aparent,即可得到父对象
5)管理器
模型类名.objects.all()
objects是什么
objects是django自动生成的管理器对象,通过这个管理器可以实现对数据的查询。
object是models.Manager类的一个对象。自定义管理器之后Django不再帮我们生成默认的objects管理器。
自定义管理器
1>自己创建models.Manager类的实例对象,实例对象名则会替代objects
2>创建models.Manager的子类,在子类中可以实现的功能:改变查询的结果集;添加额外的方法
models.Manager子类中使用self.model可以直接获取当前模型类的类名
6)元选项
Django默认生成的表名:
应用名小写_模型类名小写
元选项:
需要在模型类中定义一个元类Meta,在里面定义一个类属性db_table就可以指定表名了。
5.视图
1)视图功能
接收请求,进行处理,与M和T进行交互,返回应答。
返回html内容HttpResponse,也可能重定向redirect,还可能是JsonResponse。
2)视图函数使用
1>使用
a 定义视图函数
request参数必须有,是一个HttpRequest类型的对象。参数名可以变化,但不要更改。
b 配置url
建立url和视图函数之间的对应关系。
2>url配置的过程
a 在项目的urls文件中包含具体应用的urls文件,在具体应用的urls文件中包含具体url和视图的关系。
b url配置项是定义在一个名叫urlpatterns的列表中,其中的每一个元素就是一个配置项,每一个配置项都调用url函数。
3)错误视图
setting.py文件中,有一个参数DEBUG
开发过程中,这一参数默认为True,页面报错时会详细报错。为了安全,当项目实际应用时,要将这一参数改为False。同时设置 ALLOWED_HOST=[‘*’]
404:找不到页面,如果要显示自定义的页面,在templates目录下自定义一个404.html文件。url配置错误或url没有配置
500:服务器端的错误,视图出现错误
4)捕获url参数
进行url匹配时,把所需要捕获的部分设置成一个正则表达式组,这样django框架就会在自动把匹配成功后相应组的内容作为参数传递给视图函数。
1>位置参数
位置参数,参数名可以随意指定
2>关键字参数
在位置参数的基础上给正则表达式组命名即可。
?P<组名>
关键字参数,视图中参数名必须和正则表达式组名一致。
5)登录案例
浏览器的请求包含在request参数中
POST:提交的参数在请求头中。数据安全性高
GET:提交的参数在url中
1>显示出登录页面
a 设计url,通过浏览器访问login.html
b 设计url对应的视图函数login
c 编写模板文件login.html
2>登录校验功能
a 设计url,点击登录页的登录按钮发起请求
b 设计url对应的视图函数login_check
接收表单提交过来的数据
request.POST:保存的是post方式提交的参数
request.GET:保存的是get方式提交的参数
这两个数据都保存在 QueryDict中
使用QueryDict.get()来获取数据
进行登录校验,若用户名密码正确则跳转到登录成功页。若失败再跳转到登录页面。redirect
c 登录成功后调整转到首页。
3>ajax
异步的JavaScript
不重新加载页面的情况下,对页面进行局部的刷新。
$.ajax({
“url”: 请求地址,
“type”: 请求方式,
“datatype”: 预期返回的数据格式,
“data”: 参数,
}).success(function(data){
//执行成功后的回调函数
})
浏览器发送ajax请求,网站进行处理,return JsonResponse(…),返回json数据,执行回调函数。
返回的数据就保存在function的data参数中。
静态文件配置:在setting.py文件中写入STATIC_URL和STATICFILES_DIRS
6)ajax同步异步
发送ajax请求之后,浏览器不会等待请求结束就会继续向下执行,json回复到来之后才会执行ajax的回调函数。
在ajax中将async的参数设置为false,变为同步。
7)ajax登录案例
1>首先分析出请求地址时需要携带的参数
视图函数处理完成之后,所返回的json的格式
2>显示出登录页面
ajax请求不可重定向
6.状态保持
1)状态保持
http协议是无状态的,下一次去访问一个页面时并不知道上一次对这个页面做了什么。
2)cookie
浏览器发送请求,服务器进行处理,设置cookie信息,response.set_cookie,服务器把cookie交给浏览器保存,浏览器再次请求时,把cookie发送给服务器。
设置cookie时,需要一个HttpResponse类的对象或者是它子类的对象,然后是set_cookie函数。set_cookie中 max_age和expire都可以设置cookie的过期时间,前者单位为秒,后者为时间
1>定义
cookie是由服务器生成,存储在浏览器端的一小段文本信息。
2>特点
a 以键值对方式进行存储
b 通过浏览器访问一个网站时,会将浏览器存储的跟网站相关的所有cookie信息发送给该网站的服务器。request.COOKIES 是一个字典
c cookie是基于域名安全的。
d cookie是又过期时间的,如果不指定,默认关闭浏览器之后cookie就会过期。
3)session
浏览器访问服务器,服务器进行处理,设置session信息,保存在表中,保存的相应数据的主键是唯一的标识码,设置一个cookie sessionid,cookie sessionid返回给浏览器,浏览器保存sessionid,即唯一标识码。当浏览器再次访问服务器,根据唯一标识码sessionid,获取session信息,取出来的session保存在request.session属性中
1>定义
session存储在服务器端
2>特点
a session是以键值对进行存储的
b session依赖于cookie,唯一标识码sessionid保存在cookie中
c session也是有过期时间,如果不指定,默认两周就会过期
设置session:request.session[‘username’]=’smart’
获取session:request.session[‘username’]
3>对象及方法
a 以键值对的格式写session
request.session[‘键‘]=值
b 根据键读取值
request.session.get(‘键‘,默认值)
c 清除所有session,在存储中删除值部分
request.session.clear()
d 清除session数据,在存储中删除session的整条数据
request.session.flush()
e 删除session中的指定键及值,在存储中只删除某个键及对应的值
del request.session[‘键‘]
f 设置会话超时时间,如果没有指定过期时间则两个星期后过期
request.session.set_expiry(value)
value为整数时,则在value秒后过期
value为0,浏览器关闭后过期
value为None,默认两周之后过期。
4>session记住登录状态
request.session.has_key(‘islogin‘)
判断session是否有上面的参数。
4)cookie和session的应用场景
cookie:记住用户名,安全性要求不高
session:涉及到安全性要求比较高的数据。如,银行卡账号、密码等
7.模板templates
1)模板的功能
产生html,控制页面上展示的内容。模板文件不仅仅是一个html文件。
模板文件包含两部分内容:
1>静态内容:css,js,html
2>动态内容:用于动态去产生一些网页内容,通过模板语言产生。
2)模板文件的使用
1>加载模板文件loader.get_template
获取模板文件的内容,产生一个模板对象。
2>定义模板上下文RequeseContext
给模板文件传递数据
3>模板渲染产生html页面内容 render
用传递的数据替换相应的变量,产生一个替换后的表中html内容。
render方法即可完成上面的步骤。
3)模板文件加载顺序
1>首先去配置的模板目录下面去找模板文件
2>去INSTALLED_APPS下面的每个应用里去找模板文件,前提是应用中必须有templates文件夹。
4)模板语言
模板语言简称为DTL。
1>模板变量
模板变量名是由数字,字母,下划线和点组成的,不能以下划线开头。
使用模板变量:{{模板变量名}}
可能是字典、列表或对象。
2>模板标签
{% 代码段 %}
// for循环:
{% for x in 列表 %}
#列表不为空时执行
{% empty %}
#列表为空时执行
{% endfor %}
可以通过{{forloop.counter}}得到for循环遍历到了第几次
{% if 条件 %}
{% elif 条件 %}
{% else %}
{% endif %}
关系比较操作符:> < >= <= == !=
注意:进行比较操作时,比较操作符两边必须有空格。
逻辑运算:not and or
3>过滤器
过滤器用于对模板变量进行操作。
date:改变日期的显示格式
length:求长度。字符串,列表,元组,字典长度
default:设置模板变量的默认值
格式:模板变量|过滤器:参数
自定义过滤器。
新建一个py文件,导入library,创建一个Library类的对象
@register.filter
def 自定义函数
调用时:if 变量名|自定义函数
如果自定义函数有一个参数,则调用时无需传参数;如果自定义函数不止一个参数,则调用时需要传参数。
4>模板注释
单行注释 {# 注释内容 #}
多行注释
{% comment %}
注释内容
{% endcomment %}
5)模板继承
继承父模板的导航条、版权信息等
{% extends ‘父模板地址’ %}
页面不同的地方,需要在父模板中预留位置。
{% block 块名 %}
{{ block.super }} 获取父模板中块的默认内容
重写的内容
{% endblock 块名%}
正在父模板和子模板中都写入块
6)html转义
很多符号经过浏览器会发生html转义为特定字符
通过safe过滤器可以避免转义
{% autoescape off %}
{% endautoescape %}
上面块中写入的内容不会发生转义
模板硬编码默认不会经过转义
手动转义:手动输入转义字符。
8.基于模板登录案例
1)登录修饰器
有些网页需要登录之后才能访问,可以在这些网页的view函数前加验证登录的修饰器。
2)csrf攻击
1>登录正常网站之后,浏览器保存了sessionid,并且没有退出
2>之后,访问了第三方网站,并且点击了页面上的按钮,第三方网站会偷取浏览器sessionid,进行违规操作。
Django防止csrf的方式:
1>Django默认启用了csrf防护,只针对post方式
2>表单post提交数据时加上{% csrf_token %}
标签
防御原理
1>渲染模板文件时在页面生成一个名字叫做csrfmiddlewaretoken的隐藏域
2>服务器交给浏览器保存一个名字为csrftoken的cookie值
3>提交表单时,两个值都会发给服务器,服务器进行比对,如果一样,则csrf验证通过,否则失败。
3)验证码
防止暴力请求,加入验证码功能,减轻业务服务器、数据库服务器的压力
4)反向解析
当html文件名发生改变时,反向解析可以在不修改代码的情况下正常进入页面。
根据url正则表达式的配置动态的生成url
在项目urls中包含具体应用的urls文件时指定namespace
在应用的urls中配置指定name
在模板文件中使用时,格式如下:
{% url'namespace名字:name' %}
带位置参数:
{% url'namespace名字:name' 参数 %}
带关键字参数:
{% url'namespace名字:name' 关键字参数 %}
在重定向的时候使用反向解析:
from django.core.urlresolvers import reverse
无参数:
reverse('namespace名字:name名字')
如果有位置参数:
reverse('namespace名字:name名字',args = 位置参数元组)
如果有关键字参数:
reverse('namespace名字:name名字',args = 位置参数字典)
9.django功能-静态文件、中间件、后台
1)静态文件
在网页使用的css文件,js文件和图片叫做静态文件。
1>使用
a 新建静态文件夹
static
b 配置静态文件所在的物理目录。settings.py
2>加载目录
STATICFILES_FILES
3>动态显示
文档说明下加一行
{% load staticfiles %}
图片地址一处写入:
{% static ‘images/mm.jpg‘ %}
2)中间件
Django框架预留的函数接口,让我们可以干预请求和应答的过程
例子:禁止指定ip访问网站
1>获取浏览器端的ip地址
使用request对象的META属性:
request.META[‘REMOTE_ADDR‘]
2>使用中间件
a 新建middleware.py文件
b 定义中间件类
c 注册中间件类
浏览器请求到达网站,首先产生request对象,调用中间件类中的process_request函数,然后进行url匹配 ,调用中间件类中的process_view,调用view,调用中间件类中的process_response,返回给浏览器。