django 高级扩展-中间件-上传图片-分页-富文本-celery
""" django 高级扩展 一、静态文件 1.css,js,json,图片,字体等 2.配置setting,在最底下设置静态文件目录,写入下面代码 #配置静态文件目录 STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static') ] 3.在html中的调用方式 首在html开头先写:{% load static from staticfiles %} #如果STATIC_URL 改变html不用一个一个去改路径 举例 {% load static from staticfiles %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> {# 这个是css调用 #} <link rel="stylesheet" type="text/css" href="{% static 'users/css/style.css' %}> {# 这个是js调用 #} {# <script type="text/javascript" src="/static/users/js/jquery-3.1.1.min.js"></script>#} <script type="text/javascript" src="/static/users/js/suck.js"></script> </head> <body> <h1>高级扩展程序</h1> <img src="/static/users/img/ceshi.jpg" /> <hr> {#此种方式调用是配合开头,以防STATIC_URL路径变了#} <img src="{% static 'users/img/ceshi.jpg' %}" /> </body> </html> 二、中间件 概述:一个轻量级,底层的插件,可以介入django的请求与响应 本质:一个python类 路径:在setting中的MIDDLEWARE = 里进行配置 方法: 1.__int__ 不需要传参数,服务器响应第一个请求的时候自动调用,用于确定是否启用该中间件 2.process_request(self,request) 在执行视图之前被调用(分配url,匹配视图之前),每个请求上都会被调用,返回None或者HttpResponse对象 3.process_view(self,request,view_func,view_args,view_kwargs) 调用视图之前执行,每个请求上都会被调用,返回None或者HttpResponse对象 4.process_template_response(self,request,response) 在视图刚好执行完后被调用,每个请求上都会被调用,返回None或者HttpResponse对象 接下来再使用render 5.process_response(self,request,response) 所有响应返回浏览器之前调用,每个请求上都会被调用,返回HttpResponse对象 6.process_exception(self,request,exception) 当视图抛出异常时调用,返回HttpResponse对象 三、自定义中间件 1.工程的目录先创建middleware目录,在里面创建users目录 2.创建一个python文件 3.举例 from django.utils.deprecation import MiddlewareMixin class myMiddl(MiddlewareMixin): def process_request(self,request): print("get参数为:",request.GET.get('a')) 四、使用自定义的中间件 1.配置setting文件,在MIDDLEWARE中添加 'middleware.users.myMiddl.myMiddl', 格式:app名.Py的文件名.py文件里的函数名 五、上传图片 概述:文件上传的时候,文件数据存储在request.FILES属性中 注意:上传文件必须是post请求 注意:在html中的form表单上传文件需要加enctype="multipart/form-data",否则上传不上去 例: <form method="post" action="/savefile/" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="上传"> </form> 存储路径:在static目录下创建upfile目录用于存储上传的文件 配置setting文件: # 上传文件目录(注意在'static\upfile'中liux用/此斜杠,windwos用\反斜杠) MDEIA_ROOT=os.path.join(BASE_DIR,r'static\upfile') 代码示例 HTML的示例 <body> <form method="post" action="/savefile/" enctype="multipart/form-data"> {% csrf_token %} <input type="file" name="file"> <input type="submit" value="上传"> </form> </body> VIEWS的示例 def upfile(request): return render(request,'users/upfile.html') import os from django.conf import settings def savefile(request): if request.method == 'POST': f = request.FILES['file'] #合成文件在服务器端路径 filePath = os.path.join(settings.MDEIA_ROOT,f.name) with open(filePath,'wb') as fp: for info in f.chunks(): fp.write(info) return HttpResponse('ok') else: return HttpResponse('上传失败') 六、分页 1.Paginator对象 创建对象: 格式 Paginator(列表,整数) 返回值 返回分页对像 属性: count 对象总数 num_pages 页面总数 page_range 页码列表 [1,2,3,4,5] 页码从1开始 方法: page(num) 获得一个page对象,如果提供的页码不存在会抛出'invalidpage' 异常: 一、invalidpage 当向page()传递的是一个无效的页码时输出 二、PageNotAnInteger 当向page()传递的不是一个整数时输出 三、EmptyPage 当向page()传递一个有效值,但是该页面时没有数据输出 2.Page对象 创建对象:Paginator对象的page()方法返回得到page对象,不需要手动创建 属性: object_list 当前页面上所有数据对象列表 number 当前页的页码值 paginator 当前page对象关联的paginator对象 方法: has_next() 判断是否有下一页,如果有返回True has_previous() 判断是否有上一页,如果有返回True has_other_pages() 判断是否有上一页或下一页,如果有返回True next_page_number() 返回下一页的页码,如果下一页不存在,抛出invalidpage异常 previous_page_number() 返回上一页的页码,如果下一页不存在,抛出invalidpage异常 len() 返回当前页的数据(对象)个数 Paginator对象与Page对象 代码示例: 1.配置url url(r'^studentpage/(\d+)/$',views.studentpage), 2.配置view from .models import Students from django.core.paginator import Paginator def studentpage(request,pageid): alllist=Students.objects.all() #这个是每页分成3个 paginator = Paginator(alllist,3) #这个是每次拿1页 pagelist = paginator.page(pageid) return render(request,'users/studentpage.html',{'students':pagelist}) 3.配置html <body> <ul> {% for stu in students %} <li> {{ stu.sname }}--{{ stu.sgrade }} </li> {% endfor %} </ul> <ul> {% for index in students.paginator.page_range %} {#这边是判断当前页码是否相等,如果相等就不能点击自己的当前#} {% if index == students.number %} <li> {{ index }} </li> {% else %} <li> <a href="/studentpage/{{ index }}/">{{ index }}</a> </li> {% endif %} {% endfor %} </ul> </body> 七、ajax 需要动态生成,请求json数据 八、富文本 安装 pip install django-tinymce 在站中使用(注意:要确定主url中是否开启: path('admin/', admin.site.urls), 否则无法建超级管理员 1.配置setting文件INSTALLED_APPS里添加 'tinymce' 2.并在setting文件最底下添加如下: #富文本 TINYMCE_DEFAULT_CONFIG = { 'theme':'advanced', 'width':600, 'height':400, } 3.在models创建一个模型类,并进行牵移,python manage.py makemigrations 和 python manage.py migrate from tinymce.models import HTMLField class Text(models.Model): str = HTMLField() 4.在工程里的admin.py中配置站点: from .models import Text admin.site.register(Text) 5.创建超级管理员并设置账号和密码 python manage.py createsuperuser 6.登陆并点击text就可以进行编辑 http://127.0.0.1:8000/admin 在定义视图中使用 示例: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>富文本</title> {# 不管路径有没有,直接按下写,引入 #} <script type="text/javascript" src="/static/tiny_mce/tiny_mce.js"></script> <script type="text/javascript"> tinyMCE.init({ 'mode':'textareas', 'theme':'advanced', 'width':800, 'height':600, }) </script> </head> <body> <form action="/editsave/" method="post"> <textarea name="str">suck is good man</textarea> <input type="submit" value="提交"> </form> </body> </html> celery 文档网址:http://docs.jinkan.org/docs/celery/ 1.用户发起request,并且要等待response返回,但是在视图中有一些耗时的操作,导致用户可能会很久才接收到response, 2.网站每一段时间要同步一次数据,但是html请求是需要触发, 解决: 1.celery来解决,将耗时的操作放到celery中执行 2.使用celery定时来执行 celery 任务:task 本质是一个python函数,将耗时操作封闭成一个函数 队列:queue 将要执行的任务放队列里 工人:worker 负责执行对列中的任务 代理:broker 负责调度,在部署环境中使用redis 安装:一共安装三个 pip install celery pip install celery-with-redis pip install django-celery 配置setting 1.在INSTALLED_APPS添加 'djcelery', 并在setting最底下创建如下: #celery import djcelery djcelery.setup_loader() #初始化队列 BROKER_URL='redis://weilai@127.0.0.1:6379/0' CELERY_IMPORTS = ('users.task') 2.在应用的(users)目录下创建task文件 3.迁移(执行python manage.py migrate,不需要生成迁移文件,直接执行此句)生成celery需要的数据库 4.在工程目录下的xinqidain里创建celery.py,并放下下面代码: from __future__ import absolute_import import os from celery import Celery from django.conf import settings os.environ.setdefault('DJANGO_SETTINGS_MODULE','whthas_home.settings') app = Celery('portal') app.config_from_object('django.conf:settings') app.autodiscover_tasks(lambda:settings.INSTALLED_APPS) @app.task(bind=True) def debug_task(self): print('Request:{0!r}'.format(self.request)) 5.在工程目录下的xinqidain的目录的__inin__.py添加以下句子 from .celery import app as celery_app """