Django开发流程
创建一个django项目:命令:django-admin startproject 项目名
进入到项目并创建一个应用:命令:python manage.py startapp 应用名
确保是使用的python2环境,file -- settings -- Project: -- Project Interpreter -- 更改环境
将应用添加到项目中:在项目下的settings文件中找到INSTALLED_APPS,在最后面写入应用名
在总的项目文件中创建一个模板,templates,在templates下创建一个目录,目录名跟应用同名,在该目录下则可以创建html文件,用于渲染网页
要想使用模板还得在settings文件中找到TEMPLATES,找到DIRS,在列表中写入:os.path.join(BASE_DIR, 'templates')
更改时区的方法:在settings文件中找到TIME_ZONE : 设置为 'Asia/Shanghai'
将语言更改为中文: 在settings文件中找到LANGUAGE_CODE : 设置为 'zh-hans'
设置url(路由): 在项目下找到url,这就是路由的配置地方,但是一般路由的配置是在应用下的urls,这个文件需要自己创建,
创建一个子路由: 在应用下创建一个urls.py文件
让项目中的路由跟子路由联系起来: 在父路由中导入include,然后再新创建一个路由,url(两个参数),第一个参数是要跟网址做匹配的正则
第二个参数: include('子路由的路径,一般是:应用.urls')
然后配置子路由:跟父路由一样导入url模块,定义一个同名的列表 urlpatterns = [],列表中就可以写url()函数了,第一参数同上
第二个参数则是视图函数,还得在子路由中导入views中的视图函数,视图函数在应用下的views.py中编写
编写视图函数: 在views.py中定义函数,接收一个参数request,函数内返回一个response对象:return render()
render中,第一个参数是request,第二个参数是要返回的模板路径(也就是html文件,应用名/模板名)
Django-model
模型类 --- models.py(主要用与数据库跟django的交互)
ORM :
MVC框架中一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,使开发时不需要面对sql语句,而是通过
面向对象来操作数据库
model的作用是定义出对象模型,一般都是和数据库里表对应,一个表一个model类,表里面的字段对应model类的属性,
使用models模块,我们可以操作数据库,但是不需要写sql语句,model模块中都给我们封装好了
在models中定义类,继承models.model , model中内部写了sql语句,只需要调用就行了,类对应的也就是数据库中的表
django使用mysql数据库(链接数据库),在setting.py文件中配置
DATABASES = {
'defult':{
'ENGINE':'django.db.backends.mysql',
'NAME':'test2' #数据库名
'USER': '用户名'
'PASSWORD': '密码'
'HOST': '数据库服务器ip,本地可以使用localhost'
'PORT': '端口,默认为3306'
}
在项目的init文件内导入pymysql,并且写上pymysql.install_as_MySQLdb()
在定义类中属性时,需要自定义字段类型,例如Charfield,Booleanfield,
字段类型:
Charfield : 字符串 , Booleanfield : 布尔值 , IntegerField:整数
在这些字段类型函数里面,参数可以写字段选项(限制字段),字段默认值等
参数中还可以定义一个verbose_name = ""
属性值就是在admin后台显示的信息,等于是自定义在admin网页中显示的字段名
元选项():
在指定的模型类内定义一个元类,不用继承任何类:
1.可以自定义更改数据库中表的名字
db_table='自定义的表名'
2.以汉字形式在后台管理页面显示表名(更改在admin中显示的模型类名)
verbose_name = ''
verbose_name_plural = verbose_name
小总结:
在admin后台管理中用中文显示表信息
1.模型类中: def __str__(self):
return self.name
2.定义字段属性的函数参数中,传入verbose_name='',admin中指定的字段会替换成该值
3.模型类中定义一个Meta类,不继承任何类,定义类属性,verbose_name = '需要修改成的值'
管理器manager:
管理器是模型类的一个属性,用于将对象和数据表映射
任何一个模型类django都对默认创建一个objects管理器,用于和数据库做交互,是ORM的核心
自定义管理器(可以定义多个):
定义一个类,继承models.Manager,
重写方法:
get_queryset(self):
return super(BookInfoManager,self).get_queryset()
作用:
自定义后,更改查询集(更改之后就是使用自定义的管理器查询了),还可以在自定义类中加上查询时的过滤方法,这个方法在查询时的all()内部就调用了
还可以增加模型类对象的创建方法(更快速):
推荐使用第 1 种
1.在自定义管理器类中定义一个模型类对象创建方法,不过是对象的方法,然后下次创建模型类对象时也可以直接传参
在方法的最下面要记得返回在方法中创建的对象
创建模型类对象:
b = 模型类.自定义的管理器.创建的对象方法(传入数据)
2.默认在模型类中是不能写init方法的,所以就需要定义一个类方法来代替init接收参数
在类中定义一个类的方法,然后再创建模型类对象的时候,可以直接传入要设置的表中信息,
在方法的最下面要记得返回在方法中创建的对象
创建模型类对象:
b = 模型类.类方法(传入的数据则是表中的数据)
Django-admin
#admin网页中可以维护数据
创建超级用户:
python manage.py createsuperuser
进入admin网页中会提示输入用户密码,输入后便可进入用户管理页面
在admin网页中可以直接管理数据,也可以自定义数据的显示方式
注册用户:
在应用的admin中注册(将模型类添加到admin中)
导入models模快--> admin.site.register(models模块中的类名)
运行项目后,可以在admin网页中,来查看用户,也会有表的数据,
自定义管理页面(admin网页中)
在models中定义类,继承admin中的ModelAdmin,
并且在register注册的方法中的第二参数写上类名,表示遵循这个页面的改变
列表页的显示:
类里写上例如
(字段排序):
list_display = ['id','btitle','bpub_date'](按照自定义的方式排序显示)
过滤字段,出现在右边:
list_filter = ['btitle'](按照btitle过滤)
搜索字段,出现在上方
search_fields = ['btitle'](按照btitle进行搜索)
分页
list_per_page = 2
添加修改页
fieldsets = [
('base',{'fields':['btitle']}),
('super',{'fields':['bpub_date']})
]
关联注册:
在admin.py中新定义一个类,继承admin.StackedInline(也可以继承admin.TabularInline,显示的是表格形式的),
用来关联注册,图书跟作者,是一对多的关系(一本书可以由几个人写成)
model = HeroInfo (表示关联model.py中的哪个类,)
extra = 2 (表示关联的个数)
嵌入(也可以嵌入多个)
在管理类(上面的管理网页显示)中写上
inlines = [HeroInfoInline] (显示在网页中)
Django-views
view.py中主要编写业务逻辑的代码,负责接收接收web请求和返回web响应
url :
在应用下创建一个urls.py文件为子路由,urlpatterns是一个url()对象实例的列表,一个url有三个参数,
url(正则,视图函数,名称),若需要从url中捕获一个值,需要在他周围设置一对小括号
自定义参数:
在url中将正则用小括号括起来就代表会将该正则传给视图函数中,该视图函数必须定义参数接收,
在接收参数时,在括号内正则前,写上?P<选择接收的参数,也就是在视图函数中定义的参数名>,尖括号中的参数就会
指定传给视图函数中同名的参数,没有顺序可言
浏览器中分页显示信息:
在内存中将数据库的sql查询结果序列化后保存起来,按配置的每页记录数,返回不同的列表
在报404错误时,自己写一个页面返回,在templates文件中写一个404.html,在每次报404错误就会显示404.html页面
但是需要设置以下两点
1.settings文件中设置是否调试,设置DEBUG=False,默认为True,开发中为了调试一般就设置为true
2.ALLOWED_HOSTS = [允许访问的电脑地址],括号中写'*'表示任何
3.在模板目录下创建一个404的模板文件
在网页中输出报错路径
request_path
request对象
含有的属性:path(请求路径) ,method(请求方式)都是字符串
方法
is_ajax(),判断是否是使用的ajax
网址中传入值,并在视图函数中使用request对象接收:
在url后面加上?,每个值用 & 隔开,例如: index/?a=1&b=2
通过request.GET['a']获取数据
如果是index/?a=1&a=2,也就是一键对多值,使用request.GET.getlist()获取,
得到的是一个列表
POST请求方式:
一般用于表单,表单项的name属性,就是在试图中的键,
获取一键对应一值: request.POST['表单项的name']
获取一键对多值 : request.POST.get('表单项的name')
response对象:
content :表示返回的内容
charset : 表示response采用的编码字符集,字符串类型
status_code : 响应的HTTP响应代码
content-type : 指定输出的MIME类型
Django-sessionAndCookie
cookie和session的区别:
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
5、所以个人建议:
将登陆信息等重要信息存放为SESSION
其他信息如果需要保留,可以放在COOKIE中
cookie :
存储在浏览器中的一段文本信息
cookie返回给浏览器信息(键值对)
set_cookie(key,value='',max_age=None,expires=None)
key , value都是字符串类型,
max_age 和 expires参数都是过期时间设置,二选一,不设置的话默认两个星期过期
response = HttpResponse() ,
response.set_cookie('t','tt')
return response
本网站的cookie不能在其他网站访问
response的子类HttpResponseRedirect重定向
需要重定向的网页HttpResponseredirect('需要定向到的视图url')
一般直接使用 renturn redirect('需要定向到的视图url')
无状态:
HTTP协议的特点,无法记录之前的状态,不会记得用户访问过什么页面,
实现状态保持的两种方法:
session cookie
session:
session保存数据默认是保存到了数据库,所以使用之前还要迁移
session就是一个字典对象
设置session数据存储的位置:
在settings文件中添加:
SESSION_ENGINE='django.contrib.sessions.backends.db' (默认的,存储在数据库)
本地缓存:
SESSION_ENGINE='django.contrib.sessions.backends.cache'
数据库和缓存同时使用:
SESSION_ENGINE='django.contrib.sessions.backends.cache_db'
redis:
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 0
SESSION_REDIS_PASSWORD = ''
SESSION_REDIS_PREFIX = 'session'
启用session:
setting文件中:
向INSTALLED_APPS列表中添加:
'django.contrib.sessions',
向MIDDLEWARE_CLASSES列表中添加:
'django.contrib.sessions.middleware.SessionMiddleware',
禁用这些会话可以节省性能消耗
使用session:
往session中写数据:
request.session['键']=值
以base64的编码存储在数据库django_session表中
根据键获取会话的值
request.session['键']
也可以request.session.get('键',默认值(不写为None)),拿不到数据会返回默认值
判断session中是否有指定数据:键值
清除所有会话
clear()
删除当前的会话数据并删除会话的cookie
flush()
删除会话
del request.session['键']
设置会话过期时间:
set_expiry(value)
如果没有指定,则两个星期后过期
如果value是一个整数,会话将在values秒没有活动后过期
若果value是一个imedelta对象,会话将在当前时间加上这个指定的日期/时间过期
如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期
如果value为None,那么会话永不过期
Django-templates
csrf(跨站攻击):
取消csrf验证,只有请求方式是POST才需要
注释中间件,在settings文件中的MIDDLEWARE_CLASSES ,找到含有csrf的一行,将其注释
但是直接注释等于关闭掉了验证,不安全
使用如下方法:
在表单的开头标签下面写上 {% csrf %}
模板中引入静态文件:
{% load staticfile %}
django模板中的语言称为 :
简称DTL
输出变量:{{ 变量 }}
语法: {% for i in xx %}
{{ forloop.counter }} -- 可以得到当前循环是第几次
{% if .. %}
逻辑1
{% elif .. %}
逻辑2
{% else %}
逻辑3
{% endif .. %}
结尾
{% empty %} --如果循环的对象空的就走这
{% endfor %} --结尾
过滤器(基本是运算)太多,用的时候网上查
语法:
{% 变量|过滤器 %}
例如 : 变量|divisibleby:'2' 整除2
过滤器串联:
变量|过滤器1|过滤器2
注释
{# 单行注释 #}
{% comment %}
多行注释
{% endcomment %}
反向解析
好处:
变更url后,不需要更改对应链接的的属性了,因为链接属性在定义的时候就自动生成了与url相匹配的地址
例如: href = {% url 'app:show' '指定传给url的参数,可以多写或不写' %}
父url起别名 include第三个参数,namespace='',为了区分应用
子url: name = ''
模板继承
block标签,在父模版中预留一个区域,让子模版来继承(挖坑),
{% block 坑名%}
预留的区域
{% endblock 坑名 %}
extends,在子模版中继承
{% extends '继承于的模板' %}
继承父模版中预留的区域(填父模板的坑)(子模板中的内容必须写在坑中)
{% block 坑名 %}
子模版需要写的内容
{% endblock 坑名 %}
传参
在子模版的视图函数中传入参数在祖先模板中也可以使用
三层模板继承
在主模板base中写好html代码,挖一个坑,在base_user中继承base,填base中的坑,然后再挖一个坑,
写一个user1和user2来继承base_user,并且填base_user中的坑
可以跨层填坑: 子模板可以填祖先模板挖的坑
html转义
django默认转义,可以有办法来设置不转义
如果在上下文中传递html代码,django会自动转移成其他的字符,会转义的字符(< > ' " &)
可以在变量后加个safe过滤器,就等于关闭了转移,django会将他识别为html代码执行
或者将不需要转义的代码写在{% aotuescape off %}{% endautoescape %}标签中
在模板中定义的变量默认不转义 ,定义变量(使用过滤器) : {% 变量名|default: '...' %}
想转义就要手动转义
内存文件的操作
导入cStringIO模块
验证码
安装pillow
利用PIL绘制验证码
1.创建背景色
2.创建画布,
3.构造字体对象
4.创建画笔
5.创建文本内容,字体
6.绘制逐个字符(循环)
将每个随机绘入的字符保存在一个定义的空字符中
7.存入seesion保存的字符,用于验证
8.保存到内存流中,需要使用cstringIO
9.返回response对象 return HttpResponse(缓存IO对象,'图片/保存在IO中的格式')
10.新建一个表单视图网页,action写成另一个试图
11.在另一个视图中接收表单中的输入值,并与session中的字符做比较
调用对象的方法或者属性:
在views文件中实例化一个模型类的对象,然后传入上下问对象给模板,模板则可以直接调用该对象的属性或方法