session的操作补充说明
# 演示session缓存
def session_data(requset):
# session缓存 是存储在服务器的内存条cache中,但是会出现共享问题,需要把数据存储在redis中
# 第一步:安装django_redis模块
# 第二步:设置存储方案——SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
# 第三步:指定缓存配置——主要是两个地方
# BACKEND": "django_redis.cache.RedisCache", # 缓存后端
# "LOCATION": "redis://127.0.0.1:6379/1",
# 第四步:指定缓存哪个数据库 这里是数据库1
# key存在为修改,不存在为新建
# session首先把{'name':'zhangsan'} 转换成字符串类型存储在redis中,然后在进行字符串的拼接,构成sessionid 作为redis的key值
# requset.session['name']='zhangsan' # 当新建session时,会生成一个sessionid值,把值存储到cookie中
# 获取session
print(requset.session.get('name')) # 这里得到的数据类型为字符串
return http.HttpResponse('session_data')
# session依赖cookie——主要是依赖cookie的sessionid 当删除浏览器里面的cookie时,再次调用就会报错
# session的过期时间不设置或默认为None 时间默认是两周
# session过期时间如果为0 表示会话结束就删除
1-[了解]类视图的介绍
- 对比函数视图的好处:
- 代码可读性好
- 类视图相对于函数视图有更高的复用性
- 作用:
- 为了让一个视图对应的路径提供了多种不同HTTP请求方式的支持时.在Django中可以使用类来定义一个视图,称为类视图。
2-[重点]类视图的定义和使用
-
定义类视图需要继承自Django提供的父类View
-
在类视图中分别实现对应的:GET请求,POST请求…等方法处理不同业务逻辑
-
from django.views import View # 定义类视图 需要引入模块from django.views import View # 类的方法必须要继承View class LoginView(View),需要传递View参数 # 定义类视图的步骤 # 1.类视图必须继承View # 2.类视图的方法为请求方式的小写;如果是GET请求 则为def get # 3.类视图的路由 url为as_view # as_view的作用:1.将类视图的方法转换成视图函数; # 2.根据请求方法名字的小写,从视图中找到匹配的方法,定义给一个handle变量 把方法变成函数去调用 # 1.启动时,总路由——>应用路由——>应用路由的as_view # 2.发送请求 匹配路由成功,执行view函数 定义给handle 方法变成函数调用 返回响应对象 class IndexView(View): # 这里get post请求都可以发 # 发送post请求用到postman工具 def get(self,request): return HttpResponse('hello world') def post(self,request): a = request.POST.get('name') b = request.POST.get('age') c = request.POST.get('gender') print(a) print(b) print(c) return HttpResponse('python')
-
当用调试工具postman发送post请求时,需要把settings里面的Csrf注释掉
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',
]
-
配置路由时,使用类视图的as_view()方法来添加**。
-
urlpatterns = [ # 视图函数:注册 # url(r'^register/$', views.register, name='register'), # 类视图:注册 # views.RegisterView.as_view()相当于view函数 url(r'^register/$', views.RegisterView.as_view(), name='register'), ]
-
3-[了解,难点]as_view底层原理理解
- 调用流程
- as_view–>view–>dispatch
- handler = getattr(‘对象’,‘字符串’) --> get()/post()
4-[重点]类视图使用装饰器-[给类中方法添加装饰器]
-
给类视图添加装饰器作用:
- 给类中每一个视图方法都可以额外添加功能
-
实现步骤:
1.定义一个装饰器
2.在URL配置中装饰:my_decorate(DemoView.as_view()) -
扩展:
-
深度理解: 1.需要明白装饰器本质是函数,所以可以使用函数调用的方式使用装饰 2.参数一致的问题: DemoView.as_view() ---> 返回:view(request, *args, **kwargs) my_decorate装饰器内层函数: func_in(request, *args, **kwargs),参数一致所有可以这么使用
-
# 定义类视图 需要引入模块from django.views import View
# 类的方法必须要继承View class LoginView(View),需要传递View参数
# 定义类视图的步骤
# 1.类视图必须继承View
# 2.类视图的方法为请求方式的小写;如果是GET请求 则为def get
# 3.类视图的路由 url为as_view
# as_view的作用:1.将类视图的方法转换成视图函数;
# 2.根据请求方法名字的小写,从视图中找到匹配的方法,定义给一个handle变量 把方法变成函数去调用
# 1.启动时,总路由——>应用路由——>应用路由的as_view
# 2.发送请求 匹配路由成功,执行view函数 定义给handle 方法变成函数调用 返回响应对象
# class LoginView(View):
# # 定义方法时,需要传递参数
# def get(self,request):
# return http.HttpResponse('get')
#
# def post(self,request):
# return http.HttpResponse('post')
5-[重点]类视图使用装饰器-[给类添加装饰器]
-
method_decorator 作用:
- 给类视图添加装饰器
-
注意:
-
在类视图中使用为函数视图准备的装饰器时,不能直接添加装饰器,需要使用method_decorator将其转换为适用于类视图方法的装饰器。
-
method_decorator装饰器使用name参数指明被装饰的方法
-
#1. 为全部请求方法添加装饰器 @method_decorator(my_decorator, name='dispatch') #2. 为特定请求方法添加装饰器 @method_decorator(my_decorator, name='get')
-
-
如果需要为类视图的个别方法添加装饰器
-
可以直接在需要添加装饰器的方法上使用method_decorator
-
# 类视图添加装饰器 需要引入模块 from django.utils.decorators import method_decorator # 如果method_decorator写在类名上时,两个参数必须全部传递 # 如果method_decorator写在类方法上时,只需要传递一个参数就可以,默认装饰当前方法 # 参数是(装饰器名字,name='要装饰类中的哪个方法') # 在定义路由添加装饰器会装饰类视图中所有的请求方法 # 演示类视图添加装饰器 1.在路由添加装饰器 #url(r'^my_decorator',views.my_decorator(views.LoginView.as_view())), def my_decorator(func): def wrapper(request, *args, **kwargs): print('自定义装饰器被调用了') print('请求路径%s' % request.path) return func(request, *args, **kwargs) return wrapper # # 2.给类视图添加装饰器 # @method_decorator(my_decorator,name='dispath') class LoginView(View): # 定义方法时,需要传递参数 # @method_decorator()解决了@my_decorator装饰器参数传递问题 # @method_decorator(my_decorator) # 这里面的参数是(装饰器名字,name='要装饰类中的哪个方法') # 3.给某个方法进行装饰 # @method_decorator(my_decorator) def get(self,request): return http.HttpResponse('get') def post(self,request): return http.HttpResponse('post')
-
6-[了解]类视图Mixin扩展类
-
作用 :
- 类多继承 为类视图补充拓展功能, 实现代码复用。
-
步骤:
-
1.使用面向对象多继承的特性,定义扩展类。 [定义Mixin扩展类] 2.在父类中定义想要向类视图补充的方法。 [实现拓展功能] 3.类视图继承这些扩展父类。 [多继承]
class LoginView(LoginRequiredMixin,View): # 如果LoginRequiredMixin和View都有要调用的方法,先调用LoginRequiredMixin
def get(self,request):
return http.HttpResponse('get')
def post(self,request):
return http.HttpResponse('post')
7-[了解]中间件的介绍
-
作用 :
-
在Django处理视图的阶段 对请求对象&响应对象 进行拦截处理,补充额外功能,处理共性的功能。
-
# 比如: 对响应对象的返回内容类型进行统一设置: response["Content-Type"] = "application/json"
-
8-[重点]中间件的定义和使用
-
步骤:
-
1.中间件写法,类似于装饰器,写法固定 [copy即可] 2.在setting文件中注册自定义的中间件
-
# users应用中新建一个middleware.py文件 def my_middleware(get_response): print('init 被调用') def middleware(request): print('before request 被调用') response = get_response(request) print('after response 被调用') return response return middleware
-
注意:
-
1.必须接受get_response。 2.需要接收一个request对象参数,使用get_response创建一个响应对象,返回response对象。
9-[了解]执行顺序理解
-
初始化顺序:
- 由下至上
-
理解中间件的执行顺序:
-
在视图函数被处理前,中间件由上至下依次执行 在视图函数被处理后,中间件由下至上依次执行
-
注意: Django运行在调试模式下,中间件init部分有可能被调用两次
# Middleware中间件本质就是一个装饰器,只不过会装饰整个工程中所有的视图
# 中间件设置完成之后 需要在settings.py中需要注册安装
# 作用:可以控制请求被处理 当请求被处理之后,在响应时,响应对象会被中间件再处理一次
# 中间件的执行流程:当启动时就执行'init1 被调用',发送请求之后,执行'before request1 被调用'——>response = get_response(request)
# ——>return http.HttpResponse('get')——>return response
# 当出现多个中间件时,启动先执行'init2 被调用'——>'init 被调用' 因为里面的反转函数reverse 因此先执行init2
# 在请求视图被处理前,中间件由上至下依次执行
# 在请求视图被处理后即响应,中间件由下至上依次执行
def my_middleware1(get_response):
print('init 被调用') # 启动执行2
def middleware1(request):
print('before request1 被调用') # 发送请求第一步执行
response = get_response(request) # 发送请求第二步执行
print('after response1 被调用') # 响应第三步执行
return response # 响应第四步执行
return middleware1
def my_middleware2(get_response):
print('init2 被调用') # 启动执行1
def middleware2(request):
print('before request 2 被调用') # 发送请求第三步执行
response = get_response(request) # 发送请求第四步执行 返回响应对象get 执行响应第一步
print('after response 2 被调用') # 响应第一步执行
return response # 响应第二步执行
return middleware2
django自带模板的过滤器使用
- 作用:
- 让变量内容按照需求格式化输出
- 语法:
- 变量|过滤器:参数
- 系统常见过滤器:
- safe :
fdjsk
- length
- default
- date
- Y表示年,格式为4位,y表示两位的年。
- m表示月,格式为01,02,12等。
- d表示日, 格式为01,02等。
- j表示日,格式为1,2等。
- H表示时,24进制,h表示12进制的时。
- i表示分,为0-59。
- s表示秒,为0-59。
- safe :
django自定义过滤器步骤
-
template提供的内置过滤器,不够用,不灵活,就可以自己定义一个过滤器
-
自定义过滤器步骤:
-
要进行自定义过滤器的应用一定要注册,并且编写自定义过滤器的包名必须叫templatetags
-
1.在自己的app里建一个templatetags包, 并创建一个后面要在HTML文件引用的py文件
- templatetags.listreverse.py
-
2.导入template包
- from django import template
-
3.创建注册对象
- register = template.Library()
-
4.自定义函数完成列表反转,利用装饰器将注册自定义的过滤器 [ps 函数名即为过滤器名称]
-
@register.filter def do_listreverse(x): ...
-
-
-
使用:
- 5.load加载定义过滤器的py文件
- {% load listreverse %}
- 6.使用自定义的过滤器
- {{ list | do_listreverse }}
- 5.load加载定义过滤器的py文件
模板的继承
-
作用:
- 模板继承和类的继承含义是一样的,主要是为了提高代码重用,将相同的内容封装到父模板中。
-
步骤:
-
# 1.在父模板中将不同的内容,需要重写的内容使用block包含起来 {% block 名称 %} ... {% endblock 名称 %} # 2.继承父模板: {% extends "父模板路径"%} # 3.在子模板中重写block实现特定代码 {% block 名称 %} 实际填充内容 {{ block.super }}用于获取父模板中block的内容 {% endblock 名称 %}
-
Django中使用jinja2模板
-
介绍:
- 相对django默认模板引擎而言,jinja2 引擎功能齐全,速度快。
-
使用步骤:
-
1.安装jinja2模块
pip install jinja2
-
2.配置jinja2
-
新建文件jinja2_env.py
-
from jinja2 import Environment def environment(**options): env = Environment(**options) return env
-
修改settings.py配置信息
TEMPLATES = [ { 'BACKEND': 'django.template.backends.jinja2.Jinja2',#修改1 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS':True, 'OPTIONS':{ 'environment': 'jinja2_env.environment',# 修改2 'context_processors':[ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
-
-
jinja2在使用上和django自带模板差异
-
1.for循环有差异
- Forloop.counter --> loop.index
-
2.jinja2自定义过滤器
-
from jinja2 import Environment def environment(**options): env = Environment(**options) env.filter['listreverse'] = listreverse return env def listreverse(list): list.reverse() return list
-
-
-
ORM
-
介绍
- ORM:对象关系映射
-
作用:
-
#1.将定义数据库 `模型类 `--> 数据库表 #2.将定义数据库模型类中的 `属性` ---> 数据库表`字段` #3.将模型对象的操作(save,delete,get) ---> 对应sql语句,并将执行结果提交到数据库
-
-
优点:
- 只需要面向对象编程, 不需要面向数据库编写代码.
- 实现了数据模型与数据库的解耦, 屏蔽了不同数据库操作上的差异.
-
缺点:
- 相比较直接使用SQL语句操作数据库,有性能损失.
- 根据对象的操作转换成SQL语句,根据查询的结果转化成对象, 在映射过程中有性能损失.
django中使用mysql的配置
-
1.使用MySQL数据库首先需要安装驱动程序
-
pip install PyMySQL
-
2.在Django的工程同名子目录的__init__.py文件中添加如下语句
-
from pymysql import install_as_MySQLdb install_as_MySQLdb()
-
3.修改DATABASES配置信息 [copy]
-
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '192.168.140.159', # 数据库主机 'PORT': 3306, # 数据库端口 'USER': 'root', # 数据库用户名 'PASSWORD': '123456', # 数据库用户密码 'NAME': 'django_demo' # 数据库名字 } }
-
4.在MySQL中创建数据库
-
create database django_demo default charset=utf8;
-
扩展:
-
python2用到的mysql驱动叫: MySQLdb python3用到的mysql驱动叫: pymysql # 注意: 一些框架默认仍然用的是MySQLdb,但是python3已经不支持MySQLdb,取而代之的是pymysql,因此运行的时候会报 ImportError: No module named ‘MySQLdb’ # 解决方案:将pymysql转换成MySQLdb pymysql.install_as_MySQLdb()
定义模型类
-
模型类被定义在"应用/models.py"文件中
-
模型类必须继承自Model类
-
定义模型类:
from django.db import models #定义图书模型类BookInfo class BookInfo(models.Model): btitle = models.CharField(max_length=20, verbose_name='名称') bpub_date = models.DateField(verbose_name='发布日期') bread = models.IntegerField(default=0, verbose_name='阅读量') bcomment = models.IntegerField(default=0, verbose_name='评论量') is_delete = models.BooleanField(default=False, verbose_name='逻辑删除') class Meta: db_table = 'tb_books' # 指明数据库表名 verbose_name = '图书' # 在admin站点中显示的名称 verbose_name_plural = verbose_name # 显示的复数名称 def __str__(self): """定义每个数据对象的显示信息""" return self.btitle #定义英雄模型类HeroInfo class HeroInfo(models.Model): GENDER_CHOICES = ( (0, 'female'), (1, 'male') ) hname = models.CharField(max_length=20, verbose_name='名称') hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别') hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息') hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='图书') # 外键 is_delete = models.BooleanField(default=False, verbose_name='逻辑删除') class Meta: db_table = 'tb_heros' verbose_name = '英雄' verbose_name_plural = verbose_name def __str__(self): return self.hname
执行数据库迁移
-
作用 :
-
1.当表不存在的情况,根据`模型类`创建--->数据库`关系表` 2.当表已经存在的情况,当`模型类`属性修改 ----> 数据库表的`字段`跟着改变。
-
-
步骤:
-
1.生成迁移文件
-
python manage.py makemigrations
-
2.同步到数据库中【此时数据库表才会生成】
-
python manage.py migrate
-
-
注意:
- 提示:no changes detected
- 没有注册应用,迁移是发现不了models中的模型类