美文网首页
Django - 05-Django高级

Django - 05-Django高级

作者: 找呀找提莫 | 来源:发表于2020-09-10 14:56 被阅读0次

[toc]

1 静态文件

定义:
        css、js、图片、json文件、字体文件等

存储位置:
        project/static/项目名/{css,js,img,json,font,other}
        
配置settings.py
        STATIC_URL = '/static/'
        STATICFILES_DIRS = [
            os.path.join(BASE_DIR, 'static'),
        ]
        
栗子:
        目录结构:
            Project
             └─static
                └─myApp
                   ├─css
                   ├─font
                   ├─img
                   ├─js
                   ├─json
                   └─other
        index.html
                <head>
                    <meta charset="UTF-8">
                    <title>index</title>
                    <link rel="stylesheet" type="text/css" href="/static/myApp/css/style.css">
                </head>
                    <script type="text/javascript" src="/static/myApp/js/lance.js"></script>
                <body>
                    <h1>lance is a good man</h1>
                    <img src="/static/myApp/img/a.png" alt="">
                </body>
                
        style.css
                h1{color: red;}
        
        lance.js
                console.log('good man')
                

普通文件动态加载static目录:(有错误 先别用)
        index.html
                {% load static from staticfiles %}
                <!DOCTYPE html>
                ...
                <img src="{% static 'myApp/img/a.png' %}" alt="">
                
        注意:
                这时的文件的链接路径 已经不需要从static开始去写了;
                settings.py中的 STATICFILES_DIRS 配置项已经无效;
                
                

2 中间件

2.1 概述

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

2.2 方法

__init__
        不需要传参数,服务器响应第一个请求的时候调用;用于确定是否启用该中间件;

process_request(self, request)
        在分配url匹配视图之前,每个请求上都会调用;返回 None 或者 HttpResponse 对象;

process_view(self, request, view_func, views_args, view_kwargs)
        调用视图之前执行,每个请求都会调用;返回 None 或者 HttpResponse 对象;

process_template(self, request, response)
        在视图执行完成后调用,每个请求都会调用;返回 None 或者 HttpResponse 对象;
        使用 render()
        
process_response(self, request, response)
        在执行模板之后调用,每个请求都会调用;返回 HttpResponse 对象;

process_exception(self, request, exception)
        当视图抛出异常时调用;返回 HttpResponse 对象;

2.3 自定义中间件

目录结构:
        project/middleware/myApp/
        
创建中间件:
        myMiddler.py
                from django.utils.deprecation import MiddlewareMixin
                class MyMiddler(MiddlewareMixin):
                    def process_request(self, request):
                        print("GET参数为:", request.GET.get("a"))

使用中间件:
        配置settings.py,在 MIDDLEWARE 中添加:
                'middleware.myApp.myMiddleware.MyMiddle',

验证:
        刷新界面,可以看到后台,有打印信息;

3 上传图片

3.1 概述

文件上传时,文件数据存储在request.FILES属性中;

注意:
        form表单要上传文件需要加 enctype="multipart/form-data" ;
        上传文件必须是POST请求;

3.2 存储配置

存储路径
        project/static/upfile

配置 settings.py:
        MEDIA_ROOT = os.path.join(BASE_DIR, 'static/upfile')

3.3 示例

upfile.html
        <form action="/savefile/" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <input type="file" name="file">
            <input type="submit" value="上传">
        </form>
        
views.py
        def upfile(request):
            return render(request, 'myApp/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.MEDIA_ROOT, f.name)
                with open(filePath, 'wb') as fp:
                    for info in f.chunks():     # 分段读取文件内容
                        fp.write(info)
                        fp.flush()
                return HttpResponse('上传成功')
            else:
                return HttpResponse("上传失败")
                
urls.py
        url(r'^upfile/$', views.upfile),
        url(r'^savefile/$', views.savefile),

4 分页

from django.core.paginator import Paginator

4.1 Paginator对象

创建对象
        格式:
                Paginator(列表, 整数)       # (所有的数据,每页几个)
        
        返回值:
                返回分页对象

属性
        count       对象总数
        
        num_pages   页面总数
        
        page_range  
                页码列表
                [1,2,3,4,5]
                页码从1开始

方法
        page(num)
                获得一个Page对象,如果提供的页码不存在,会抛出一个 'InvalidPage' 异常

异常
        InvalidPage
                当向 page() 传递一个无效的页码时抛出;
                
        PageNotAnInteger
                当向 page() 传递一个不是整数的参数时抛出;

        EmptyPage
                当向 page() 传递一个有效,但是该页面没有数据时抛出;

4.2 Page对象

创建对象
        Paginator对象的page方法返回得到Pafe对象;
        不需要手动创建;

属性
        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()
                返回当前页的数据个数;

4.3 Paginator对象与Page对象的关系

Paginator对象 把 Student.object.all() 返回的列表分割;
使用 Paginator对象的 page方法,生成对应列表段的 Page对象;
每个Page对象,对应列表段中的内容;

4.4 示例:分页显示学生信息

studentpage.html
    <ul><li>{{ pagenum }}</li></ul>
    <ul>
        {% for stu in student %}
            <li>{{ stu.id }} | {{ stu.sname }} | {{ stu.sgrade }}</li>
        {% endfor %}
    </ul>
    <ul>
        {% for index in student.paginator.page_range %}
        {# 调用page对象的paginator方法,到达paginator类;#}
        {# 再使用paginator类的page_range方法;#}
            <li><a href="/studentpage/{{ index }}/">{{ index }}</a></li>
        {% endfor %}
    </ul>
    
views.py
        from django.core.paginator import Paginator
        def studentpage(request, pageid):
            # 所有学生的列表
            allList = Student.stuObj.all()
            paginator = Paginator(allList, 3)
            page = paginator.page(pageid)
            pagenum = page.number
            return render(request, 'myapp/studentpage.html', {"student": page, "pagenum": pagenum})

urls.py
        url(r'^studentpage/(\d+)/$', views.studentpage),

5 ajax

需要动态生成,请求json数据

栗子:
        views.py
                from django.http import JsonResponse
                def ajaxstudet(request):
                    stus = Student.stuObj.all()
                    list = []
                    for stu in stus:
                        list.append([stu.id, stu.sname, stu.sgrade])
                    return JsonResponse({"data": list})

6 富文本

pip install django-tinymce

在站点中使用
        配置settings.py文件
                在INSTALLED_APPS中添加:'tinymce',
                在末尾追加:
                        # 富文本
                        TINYMCE_DEFAULT_CONFIG = {
                            'theme': 'advanced',
                            'width': 600,
                            'height': 400,
                        }
                        
        创建一个模型类(myApp/models.py):
                from tinymce.models import HTMLField
                class Text(models.Model):
                    str = HTMLField()
                    
        配置站点(myApp/admin.py):
                from .models import Text
                admin.site.register(Text)
                

在自定义视图中使用
        urls.py
                url(r'^edit/$', views.edit),
                
        views.py
                def edit(request):
                    return render(request, 'myApp/edit.html')
                    
        edit.html
                <!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': 600,
                            'height': 400,
                        })
                    </script>
                </head>
                <body>
                <form action="">
                    <textarea name="str">lance is good man</textarea>
                    <input type="submit" value="提交">
                </form>
                </body>
                </html>

7 celery

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

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


celery解决:
        问题1: 将耗时的操作,放到celery中执行;
        问题2: 使用celery定时执行;


celery组件:
        任务tasl        本质是一个Python函数,将耗时操作封装成一个函数;
        队列queue       将要执行的任务,放到队列里;
        工人woeker      负责执行队列中的任务;
        代理broker       负责调度,在部署环境中使用redies;


安装:
        pip install celery
        pip install celery-with-redis
        pip install django-celery
       
        
配置settings.py:
        INSTALLED_APPS
                'djcelery',
                
        追加
                import djcelery
                djcelery.setup_loader()     #初始化
                BROKER_URL = 'redis://:user@IP:6379/0'
                CELERY_IMPORTS = ('myApp.task',)
            
               
创建task.py
        project/myApp/task.py


迁移,生成celery需要的数据库表:
        python manage.py migrate


在 /project/project 下创建 celery.py:
        from __future__ import absolute_import
        import os
        from celery import Celery
        from django.conf import settings
        
        os.environ.setdefault( 'DJANGO_SETTINGS_MODULES', 'whthas_home.settings')
        app = Celery('portal')
        
        app.config_from_onject('django.conf:settings')
        app.authodiscover_tasks(lambda: settings.INSTALLED_APPS)
        
        @app.task(bind=True)
        def debug_task(self):
        print('Request: {0!r}'.format(self.request))


在project/project/__init__.py中添加:
    from .celery import import app as celery_app
    









相关文章

  • Django - 05-Django高级

    [toc] 1 静态文件 2 中间件 2.1 概述 2.2 方法 2.3 自定义中间件 3 上传图片 3.1 概述...

  • 05-Django模板

    一、模板概述 模板组成HTML代码动态插入的代码(挖坑、填坑逻辑控制代码) 作用快速生成HTML页面 优点模板的设...

  • 05-Django模板

    一、模板概述 模板组成 作用 优点 模板处理 二、定义模板 变量 标签 单行注释 标签if 标签for 标签com...

  • 05-Django模板

    一、模板概述 模板组成 作用 优点 模板处理 二、定义模板 变量 标签 单行注释 标签if 标签for 标签com...

  • 05-Django模板

    一、模板概述 模板组成HTML代码动态插入的代码(挖坑、填坑逻辑控制代码) 作用快速生成HTML页面 优点模板的设...

  • Django入门与实践

    Django 简介 Django基于python的高级web开发框架。Django遵守BSD版权,初次发布于200...

  • Django 入门

    Django 2.x Python 3.x Django是基于python的高级web框架,高度集成,可以高效快速...

  • django教程--model教程之查询高级用法

    django教程--model教程之查询高级用法 上节教程我们了解了Django中model的基本使用,本节我们接...

  • aggregate和annotate方法的使用场景

    Django的aggregate和annotate方法属于高级查询方法,主要用于组合查询,是Django高手们必需...

  • Django搭建个人博客(一)

    什么是 Django Django 是一个基于 python 的高级 web 开发框架。 它能够让开发人员进行高效...

网友评论

      本文标题:Django - 05-Django高级

      本文链接:https://www.haomeiwen.com/subject/jmxirhtx.html