Django的高级功能(站点管理/中间件/文件上传/验证码/分页)

时间:2020-12-27 03:53:08
————站点管理————
1.使用站点管理
①Django中默认集成了后台数据管理页面,通过简单的配置就可以实现模型后台的Web控制台。
②管理界面通常是给系统管理员使用的,用来完成数据的输入,删除,查询等工作。
③如果没有集成,自己在settings中的INSTALLED_APPS添加 'django.contrib.admin'应用就好了:
INSTALLED_APPS = [ ...
    'django.contrib.admin',
 ...]
④创建系统管理员:python manage.py createsuperuser
根据提示创建自己的管理员——>密码8位以上且不能纯数字(root123456)
<------------------------------------------------->
2.管理界面设置
①设置为中文: settings.py 中:LANGUAGE_CODE = 'zh-hans'
②设置时区:TIME_ZONE='Asia/Shanghai'
③添加自己的数据模型:在 admin.py 中注册——>admin.site.register(xxx)
<------------------------------------------------->
3.个性化站点管理
①创建管理类:class StudentAdmin(admin.ModelAdmin):
显示规则 ——>
list_display 显示字段
list_filter 过滤字段
search_fields 搜索字段
list_per_page 分页,每页显示多少条数据
ordering 排序规则
·分组显示:
fieldsets = (
    ('班级',{fields:('sgrade')}),
    ('姓名',{fields:('sname')}),
)
·布尔值定制显示:
1.在model.py或者admin.py中定义sgender字段的显示函数:
def gender(self):
        if self.sgender:
            return '男'
        else:
            return '女'
2.设置显示的标题:gender.short_description = '性别'
3.设置显示字段:list_display = ('sname', 'sage', gender)

修改规则 ——>
fields 显示的字段
exclude 不显示的字段

范例 ——>
# 创建自定义的Admin
class StudentAdmin(admin.ModelAdmin):
     def sex_show(self):
         if self.s_sex:
             return '男'
         else:
             return '女'
sex_show.short_description = '性别'
# 显示哪些字段
list_display = ['s_name','s_age',sex_show]
# 分页,每一页最多多少数据
list_per_page = 3
# 过滤器,过滤条件字段
list_filter = ['s_name','s_age']
# 搜索
search_fields = ['s_name',]
# 排序
ordering = ['s_age',]
②注册管理类
admin.site.register(Students,StudentAdmin)
<------------------------------------------------->
4.插入管理类的同时插入默认数据
①创建班级的Admin:
class GradeAdmin(admin.ModelAdmin):
     inlines = [StudentInfo]
②创建学生信息:
class StudentInfo(admin.TabularInline):
     model = Student
     extra = 2
③注册学生管理
admin.site.register(Grade,GradeAdmin)
<------------------------------------------------->
5.定制站点信息
①在admin中继承AdminSite
class MyAdminSite(admin.AdminSite):
     site_header = '我的站点管理'
·常用定制属性:
—>site_header:管理网页的页头部的标题
—>site_title:浏览窗口显示的页面名称
—>site_url:查看站点时跳转主页路由,默认 /
②注册站点对象
site = MyAdminSite()
site.register(xxx)
③在urls路由中修改admin的跳转
from App.admin import site
url(r'^admin/',site.urls)
<------------------------------------------------->
6.个性化定制
①默认的系统模板:django/contrib/admin/templates/admin
②将需要重新定制的文件复制出来
③在自己的工程中创建相对应的子目录
④添加自己的代码

————中间件————
1.面向切面编程
①切点(钩子)
②切点允许我们动态的在原有逻辑中插入一部分代码
③在不修改原有代码的情况下,动态注入一部分代码
④默认情况,不中断传播,切点会自动愈合(自动执行原有逻辑)
⑤如果我们执行了中断操作(return,raise),没接上,会直接到程序结尾
⑥图解:
<---------------------------------------------------------------------------->
2.Django中的中间件——> 框架内置切点
__init__
#没有参数,服务器响应第一个请求的时候自动调用,用户确定是否启用该中间件
process_request(self,request)
#在执行视图前被调用,每个请求上都会调用
#不返回或返回HttpResponse对象
process_view(self,request,view_func,view_args,view_kwargs)
#调用视图之前执行,每个请求都会调用
#不返回或返回HttpResponse对象
process_template_response(self,request,response)
#在视图刚好执行完后进行调用,每个请求都会调用
#不返回或返回HttpResponse对象
process_response(self,request,response)
#所有响应返回浏览器之前调用,每个请求都会调用
#不返回或返回HttpResponse对象
process_exception(self,request,exception)
#当视图抛出异常时调用
#不返回或返回HttpResponse对象
<---------------------------------------------------------------------------->
3.自定义 中间件
用途
统计、黑名单、白名单、反爬(redis)、界面友好化(捕捉异常)
②流程
——>在工程目录下创建middleware目录
——>继承MiddleWareMixin:
class LearnAOP(MiddlewareMixin):
     def process_request(self,request):
         print('request的路径',request.GET.path)
——>覆写切点方法,实现自己的功能
· 如果我们逻辑中没有返回值,那么程序执行的时候会按照原有逻辑执行
· 如果我们做出了返回,那么程序将会从切点处切开,直接回到浏览器
——>在settings中进行注册

————文件上传————
1.创建上传文件夹
· 在static文件夹下创建uploadefiles用于存储接收上传的文件
· 在settings中配置,MEDIA_ROOT=os.path.join(BASE_DIR,r'static/uploadefiles')

2.定义上传表单
①<form action="{% url 'app:do_upload' %}" method="post" enctype="multipart/form-data">
②文件数据存储在request.FILES属性中
③文件上传必须使用POST请求方式
④举栗子:
<form method='post' action='xxx' enctype='multipart/form-data'>
     {% csrf_token %}
     <input type='file' name='icon'>
     <input type='submit'  value='上传'>
<form>

3.手动存储
存储到关联用户的表字段中,举栗子:
def savefIcon(request):
if request.method == 'POST'
     f = request.FILES['icon']
     filePath = os.path.join(settings.MEDIA_ROOT,f.name)
     with open(filePath,'wb') as fp:
         for part in f.chunks():
             fp.write(part)

4.Django内置存储
①ImageField——>需安装pillow
②FileField
③从request.FILES将文件获取出来,直接赋值给字段
④存储的时候,数据库存储的是路径
⑤存储在MEDIA_ROOT

————验证码————
1.验证码存在意义:
用户登录 ,注册以及一些 敏感操作 的时候
①我们为了防止: 服务器被暴力请求 ,或 爬虫爬取
②可以使用验证码进行 过滤 减轻服务器的压力

2.验证码需要使用绘图 Pillow
①pip install Pillow
②核心API:
——>Image:需要模式、尺寸、背景色
——>ImageDraw:绑定画布、模式、封装了绘制的API(text、point、line、arch)
——>ImageFont:手动指定字体

3.业务流程
①绘制验证码图片:
background = (10,20,30)   RGB颜色
初始化画布
image = Image.new(‘RGB’,(100,50),background)
获取画布中画笔对象
draw = ImageDraw.Draw(image)
绘制验证码,随机四个
font = ImageFont.truetype(‘path’,size)
fontcolor = (20,40,60)
draw.text((x,y),’R’,font,fontcolor)
②返回验证码内容:
# 删除画笔
del draw
#保存图片到BytesIO对象
Import io
buf = io.BytesIO()
image.save(buf,’png’)
#返回BytesIO中的内容
return HttpResponse(buf.getvalue(),’image/png’)

————分页————
1.数据加载优化

2.Paginator
①数据分页工具
②对象创建:Paginator(数据集,每一页数据数)
③属性:
——>count:对象总数
——>page_range:页码列表,从1开始
——>num_pages:页面总数
④方法:page(整数): 获得一个page对象
⑤常见错误:
——>InvalidPage:page()传递无效页码
——>PageNotAnInteger:page()传递的不是整数
——>Empty:page()传递的值有效,但是没有数据

3.Page
①具体的某一页面
②对象获得,通过Paginator的page()方法获得
③属性:
——>object_list:当前页面上所有的数据对象
——>number:当前页的页码值
——>paginator: 当前page关联的Paginator对象
④方法:
——>has_next():判断是否有下一页
——>has_previous():判断是否有上一页
——>has_other_pages():判断是否有上一页或下一页
——>next_page_number():返回下一页的页码
——>previous_page_number():返回上一页的页码
——>len():返回当前页的数据的个数