zoukankan      html  css  js  c++  java
  • 四、Django 其它

     1.静态文件

    项目中的CSS、图片、js都是静态文件。一般会将静态文件放到一个单独的目录中,以方便管理。在html页面中调用时,也需要指定静态文件的路径,

    Django中提供了一种解析的方式配置静态文件路径。静态文件可以放在项目根目录下,也可以放在应用的目录下,由于有些静态文件在项目中是通用的,

    所以推荐放在项目的根目录下,方便管理。

    1.1 使用

    (1) 新建 "static" 文件

    (2) 配置静态文件的物理路径

     引入静态文件

     

    1.2 加载目录

    STATICFILES_FINDERS=(

    'django.contrib.staticfiles.finders.FileSystemFinder',

    'django.contrib.staticfiles.finders.AppDirectoriesFinder'

    )

    1、首先读取  STATICFILES_DIRS 中的静态文件

    2、没有的话,就到每个应用中查找有没有 static 文件

    2.中间件

    Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。

    中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性,其它的MVC框架也有这个功能,名称为IoC。

    (1) 如果在某个函数显式返回,则它会跳过后续函数,直接到达 process_response

    Django在中间件中预置了五个方法,这五个方法的区别在于不同的阶段执行,对输入或输出进行干预,方法如下:

    1)处理请求前:在每个请求上,request对象产生之后,url匹配之前调用,返回None或HttpResponse对象。

    def process_request(self, request):
        pass
    

    2)处理视图前:在每个请求上,url匹配之后,视图函数调用之前调用,返回None或HttpResponse对象。

    def process_view(self, request, view_func, *view_args, **view_kwargs):
        pass
    

    (3) 只有当response实例拥有 ``render()`` 方法时 ``process_template_response()`` 才会调用

       def process_template_response(self,request,response):

       pass

    4)处理响应后:视图函数调用之后,所有响应返回浏览器之前被调用,在每个请求上调用,返回HttpResponse对象。

    def process_response(self, request, response):

      pass

    5)异常处理:当视图抛出异常时调用,在每个请求上调用,返回一个HttpResponse对象。

    def process_exception(self, request,exception):
        pass

    2.1 使用中间件

    (1) 新建middleware.py文件

    (2)  定义中间件类。

    注意:

    如果多个注册的中间件类中都有process_exception的方法,则先注册的后执行

    (3) 注册中间件类

    3.上传图片

     3.1 配置上传文件保存目录

    1 新建上传文件保存目录

    2 配置上传文件保存目录

    3.2 后台管理页面上传图片

    1) 设计模型类。

     

    2) 迁移生成表格

    3 注册模型类

    # admin 里上传图片
    admin.site.register(PicTest)

    3.3 用户自定义页面上传图片

    1) 定义用户上传图片的页面并显示,是一个自定义的表单。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>上传图片</title>
    </head>
    <body>
    <form action="/upload_handle/" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="file" name="pic"> <br>
        <input type="submit" value="上传">
    
    </form>
    </body>
    </html>

    2 定义接收上传文件的视图函数。

    request对象有一个FILES的属性,类似于字典,通过request.FILES可以获取上传文件的处理对象

    
    
    def upload_handle(request):
        '''上传图片处理'''
        # 1.获取上传文件的处理对象
        pic = request.FILES['pic']
    
        # 2.创建一个文件
        save_path = '%s/booktest/%s' % (settings.MEDIA_ROOT, pic.name)
    
        with open(save_path, 'wb') as f:
            # 3.获取上传文件的内容写到创建的文件中
            for content in pic.chunks():  # pic.chunks() 是生成器返回的文件块
                f.write(content)
        # 4. 在数据库保存
        PicTest.objects.create(goods_pic='booktest/%s' % pic.name)
    
        return HttpResponse('ok')
    
    

    在django中,上传文件不大于2.5M,文件放在内存中。上传文件大于2.5M,文件内容写到一个临时文件中。

    Django处理上传文件的两个类:

    FILE_UPLOAD_HANDLERS= (

    "django.core.files.uploadhandler.MemoryFileUploadHandler",

    "django.core.files.uploadhandler.TemporaryFileUploadHandler"

    )

    4 . 分页

    Django提供了数据分页的类,这些类被定义在django / core / paginator.py中。类Paginator用于对列进行一页n条数据的分页运算。类页用于表示第m页的数据。

    Paginator类实例对象

    • 方法_init_(列表,int):返回分页对象,第一个参数为列表数据,第二个参数为每页数据的条数。
    • 属性count:返回对象总数。
    • 属性num_pages:返回页面总数。
    • 属性page_range:返回页码列表,从1开始,例如[1, 2, 3, 4]。
    • 方法page(m):返回Page类实例对象,表示第m页的数据,下标以1开始。

    Page类实例对象

    • 调用Paginator对象的page()方法返回Page对象,不需要手动构造。
    • 属性object_list:返回当前页对象的列表。
    • 属性number:返回当前是第几页,从1开始。
    • 属性paginator:当前页对应的Paginator对象。
    • 方法has_next():如果有下一页返回True。
    • 方法has_previous():如果有上一页返回True。
    • 方法len():返回当前页面对象的个数
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>分页</title>
    </head>
    <body>
    <ul>
        {% for area in page %}
    
            <li>{{ area.atitle }}</li>
        {% endfor %}
    </ul>
    
    {% if page.has_previous %}
        <a href="/show_area{{ page.previous_page_number }}">&lt;上一页</a>
    {% endif %}
    {% for pindex in page.paginator.page_range %}
    
        {% if pindex == page.number %}
            {{ pindex }}
        {% else %}
            <a href="/show_area{{ pindex }}/">{{ pindex }}</a>
    
        {% endif %}
    {% endfor %}
    
    {% if page.has_next %}
        <a href="/show_area{{ page.next_page_number }}">&gt;下一页</a>
    {% endif %}
    </body>
    </html>
    View Code
    def show_area(request, pindex):
        '''分页'''
        # 1 查询出所有省级地区信息
        areas = AreaInfo.objects.filter(aParent__isnull=True)
    
        # 2 分页
        paginator = Paginator(areas, 10)
    
        # 3 获取第pindex的内容
        if pindex == "":
            pindex = 1
        else:
            pindex = int(pindex)
        page = paginator.page(pindex)
    
        return render(request, 'booktest/show_area.html',
                      {'page': page})
    View Code

    5.案例

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>省市县选择案例</title>
    </head>
    <body>
    <select name="" id="prov">
        <option value="">----请选择省----</option>
    </select>
    <select name="" id="city">
        <option value="">----请选择市----</option>
    </select>
    
    <select name="" id="dis">
        <option value="">----请选择县----</option>
    </select>
    
    
    <script src="/static/js/jquery-1.12.4.min.js"></script>
    
    <script>
    
        // 1 发起AJAX请求,获得所有省级地区的信息
    
        $.get('/prov', function (data) {
            // 回调函数
            res = data.data; // 获取返回的json数据
    
            prov = $('#prov');
    
            //  遍历res数组,获取每个元素 [地址id,地区标题]
            $.each(res, function (index, item) {
                id = item[0];
                atitle = item[1];
    
                option_str = '<option value="' + id + '">' + atitle + '</option>';
    
                prov.append(option_str)
            })
    
    
            /*
            for(i=0;i<res.length;i++){
    
                id =res[i][0];
                atitle = res[i][1];
                option_str = '<option value="'+ id +'">'+atitle+'</option>';
    
                //  向下拉框追加元素
                prov.append(option_str)
    
            }
    
            */
        });
    
    
        // 2 绑定prov下拉列表框的change事件
        $('#prov').change(function () {
            //  发起AJAX请求,获得所有省下面市级的信息$
            //  获取点击省的id
            prov_id = $(this).val();
    
    
            $.get('/city' + prov_id, function (data) {
    
                res = data.data; // 获取返回的json数据
                city = $('#city');
    
                // 清空
                city.empty().append(
                    '<option value="">----请选择市----</option>'
                );
    
                dis = $('#dis');
                // 清空 下拉列表
                dis.empty().append(
                    '<option value="">----请选择县----</option>'
                );
    
                //  遍历res数组,获取每个元素 [地址id,地区标题]
                $.each(res, function (index, item) {
                    id = item[0];
                    atitle = item[1];
    
                    option_str = '<option value="' + id + '">' + atitle + '</option>';
    
                    city.append(option_str)
                })
            })
    
        });
    
        // 3 绑定city下拉列表框的change事件
        $('#city').change(function () {
            //  发起AJAX请求,获得所有市下面区级的信息
            //  获取点击省的id
            city_id = $(this).val();
    
            $.get('/dis' + city_id, function (data) {
    
                res = data.data; // 获取返回的json数据
                dis = $('#dis');
    
    
                // 清空 下拉列表
                dis.empty().append(
                    '<option value="">----请选择县----</option>'
                );
    
                //  遍历res数组,获取每个元素 [地址id,地区标题]
                $.each(res, function (index, item) {
                    id = item[0];
                    atitle = item[1];
    
                    option_str = '<option value="' + id + '">' + atitle + '</option>';
    
                    dis.append(option_str)
                })
            })
    
        })
    
    </script>
    
    </body>
    </html>
    View Code
    def areas(request):
        '''省市县案例'''
        return render(request, 'booktest/areas.html')
    
    
    def prov(request):
        areas = AreaInfo.objects.filter(aParent__isnull=True)
    
        # 遍历areas并拼接处json数据
        areas_list = []
        for area in areas:
            areas_list.append((area.id, area.atitle))
    
        return JsonResponse({'data': areas_list})
    
    
    def city(request, pid):
        '''获取pid下级地区的信息'''
        areas = AreaInfo.objects.filter(aParent__id=pid)
    
        # 遍历areas并拼接处json数据
        areas_list = []
        for area in areas:
            areas_list.append((area.id, area.atitle))
    
        return JsonResponse({'data': areas_list})
    
    
    def dis(request, pid):
        '''获取pid下级地区的信息'''
        areas = AreaInfo.objects.filter(aParent__id=pid)
    
        # 遍历areas并拼接处json数据
        areas_list = []
        for area in areas:
            areas_list.append((area.id, area.atitle))
    
        return JsonResponse({'data': areas_list})
    View Code
  • 相关阅读:
    疫情环境下的网络学习笔记 python 5.8 数据库入门终章
    疫情环境下的网络学习笔记 python 5.7 navicat数据库,例题,sql注入
    疫情环境下的网络学习笔记 python 5.6 暂时看看
    疫情环境下的网络学习笔记 python 5.5 MYSql 表关系,外键
    疫情环境下的网络学习笔记 python 5.4 数据库基础
    疫情环境下的网络学习笔记 python 4.30 初识数据库
    疫情环境下的网络学习笔记 python 4.29 网络小项目
    XJOI 夏令营501-511测试11 游戏
    XJOI 夏令营501-511测试11 统计方案
    CF1197D Yet Another Subarray Problem
  • 原文地址:https://www.cnblogs.com/ykgo/p/9347229.html
Copyright © 2011-2022 走看看