django学习——高级扩展

python进阶——django学习之高级扩展

静态文件

  • css、js、图片、Json文件、字体文件等
  • 配置settings.py文件
STATIC_URL = '/static/'                # 用于图片等媒体文件
STATICFILES_DIRS = [                   # 用于文件,css、js、Json等普通文件
    os.path.join(BASE_DIR, 'static')
]
  • 在HTML文件中利用反向解析,减少工程量
{% load static from staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <img src="{% static 'myApp/img/bg.png' %}" />
</body>
</html>

中间件

概述

  • 一个轻量级、底层的插件,可以介入django的请求和响应

本质

  • 一个python类

方法

  • __init__
    不需要传递参数,服务器响应第一个请求的时候自动调用,用于确定是否启用该中间件
  • process_request(self, request)
    在执行视图之前被调用(分配url匹配视图之前),每个请求上都会调用,返回None或者HttpResponse对象
  • process_view(self, request, view_func, view_args, view_kwargs)
    调用视图之前,每个请求上都会调用,返回None或者HttpResponse对象
  • process_template_response(self, request, response)
    (1)在视图刚好执行完毕后调用,每个请求上都会调用,返回None或者HttpResponse对象
    (2)使用render
  • process_response(self, request, response)
    所有响应返回浏览器前调用,每个请求上都会调用,返回HttpResponse对象
  • process_exception(self, request, exception)
    当视图抛出异常时调用,返回HttpResponse对象

执行位置

自定义中间件

  • 在工程目录下创建middleware目录,并创建各个应用的专用中间件目录
  • 自定义中间件的类继承MiddlewareMixin
from django.utils.desprecation import MiddlewareMixin

class MyMiddle(MiddlewareMixin):
    def process_request(self, request):
        print("get:", request.GET.get("a"))

使用自定义中间件

  • 在settings.py文件中的MIDDLEWARE下添加自定义中间件的类

上传图片

概述

  • 文件上传时,文件数据存储在request.FILEA属性中
  • 注意:form表单上传文件要添加:enctype="multipart/form-data" ,且为POST请求类型

存储路径

  • 在static目录下创建upfile文件夹用于存储接收上传的文件
  • 配置settings.py:MEDIA_ROOT = os.path.join(BASE_DIR, r'static\upfile')
import os
from django.conf import settings

def upfile(request):
    return render(request, 'myApp/upfile.html')

def savefile(request):
    if request.mothed == "POST":
        f = request.FILES["file"]
        # 合成文件在服务器端的路径
        file_path = os.path.join(settings.MEDIA_ROOT, f.name)
        with open(file_path, 'wb') as fp:
            # 文件分段
            for info in f.chunks():
                fp.write(info)
        return HttpResponse("上传成功")
    else:
        return HttpResponse("上传失败")

分页

Paginator对象

  • 创建对象
  1. 格式:Paginator(列表, 整数)
  2. 返回值:返回分页对象
  • 属性
  1. count:对象总数
  2. num_pages:页面总数
  3. page_range:页码列表,[1,2,3,4,5..],从1开始
  • 方法
    page(num):获得一个Page对象,如果提供的页码不存在会抛出“InvalidPage”异常
  • 异常
  1. InvalidPage:当向page()传递一个无效的页码时抛出
  2. PageNotAnInteger:当向page()传递的页码不是一个整数时抛出
  3. EmptyPage:当向page()传递一个有效值,但是该页面没有数据时抛出

Page对象

  • 创建对象
  1. Paginator对象的page()方法返回得到Page对象
  2. 不需要手动创建
  • 属性
  1. object_list:当前页上所有的数据(对象)列表
  2. number:当前页的页码值
  3. paginator:当前Page对象关联的Paginator对象
  • 方法
方法概述
has_next()判断是否有下一页,如果有返回True
has_previous()判断是否有上一页,如果有返回True
has_other_pages()判断是否有上一页或下一个,如果有返回True
next_page_number()返回下一页的页码,如果下一页不存在,抛出“InvalidPage”异常
previous_page_number返回上一页的页码,如果下一页不存在,抛出“InvalidPage”异常
len()返回当前页的数据(对象)个数

Paginator对象与Page对象的关系

Paginator将列表分页,通过调用page(num)获得对应页码的Page对象

代码示例

# 配置url管理器
url(r'^studentpage/(\d+)/$', view.studentpage)

# 配置视图
from .models import Students
from django.core.paginator import Paginator

def studentpage(request, page_id):
    # 学生列表
    student_list = Students.objects.all()
    paginator = Paginator(student_list, 6)
    page = paginator.page(page_id)
    return render(request, 'myApp/studentpage.html', {"students":page})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>分页显示</title>
</head>
<body>
    <ul>
        {% for stu in students %}
        <li>
            {{stu.s_name}}---{{stu.s_grade}}
        </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>
</html>

Ajax

  • 概述:需要动态生成,请求JSON数据
  • 代码示例
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title </title>
    <script type="text/javascript" 
    src="/static/myApp/js/jquery-3.1.1.min.js"></script>
</head>
<body>
    <h1>学生信息列表</h1>
    <button id="btn">显示学生信息</button>
    <script type="text/javascript" 
    src="/static/myApp/js/myjs.js"></script>
</body>
</html>
$(document).ready(function() {
    document.getElementById("btn").onclick = function() {
        $.ajax({
            type:"get",
            url:"/studentsinfo/",
            dataType:"json",
            success:function(data, status) {
                console.log(data)
                var d = data["data"]
                for(var i=0;i<d.length;i++){
                    document.write('<p>'+d[i][0]+'</p>')
                }
            }
        })
    }
})
def ajaxstudents(request):
    return render (request, 'myApp/ajaxstudents.html')

from django.http import JsonResponse
def studentsinfo(request):
    students = Students.objects.al1()
    list = []
    for stu in students:
        list. append([stu.sname, stu.sage])
    return JsonResponse({"data":list})

富文本

  • 安装pip install django-tinymce
  • 在站点中使用
  1. 配置settings.py文件
    INSTALLED_APPS中添加 'tinymce'
    # 富文本
    TINYMCE_DEFAULT_CONFIG = {
        'theme': 'advances',
        'width': 600,
        'height': 400
    }
  2. 创建模型类
    from tinymce.models import HTMLField
    class Text(models.Model):
        str = HTMLField()
  3. 配置站点
    from .models import Text
    admin.site.register(Text)
  • 在自定义视图中使用
<!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>
        <textarea name="str">
            这是一个富文本
        </textarea>
    </form>
</body>
</html>

celery

文档

  • http://docs.jinkan.org/docs/celery/

问题

  • 用户发起request,并且要等待response返回,但是在视图中有一些耗时的操作,导致用户可能会等待很长时间才能接收response,用户体验差
  • 网站每隔一段时间要同步一次数据,但是http请求需要触发

解决

  • 将耗时的操作放在celery中执行
  • 使用celery定时执行

celery

  • 任务——task
    本质是一个python函数,将耗时操作封装成一个函数
  • 队列——queue
    将要执行的任务放队列里
  • 工人——worker
    负责执行队列中的任务
  • 代理——broker
    负责调度,在部署环境中使用redis

安装

  • pip install celery
  • pip install celery-with-redis
  • pip install django-celery

配置settings.py

  • INSTALLED_APPS中添加 'djcelery'
# celery
import djcelery
djcelery.setup_loader()        # 初始化
BROKER_URL = 'redis://password@127.0.0.1:6379/0'    # password为redis的密码
CELERY_IMPORTS = ('myApp.task')
  • 在应用目录下创建task.py文件
  • 迁移,生成celery需要的数据库表:python manage.py migrate
  • 在工程目录下创建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))
  • 在工程目录下的__init__.py文件中添加:from .celery import app as celery_app

--------------------待更新----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值