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
  • 相关阅读:
    无法解析导入javax.mail
    maven-assembly-plugin入门
    maven profile动态选择配置文件
    阿里巴巴Jetcache springboot使用教程
    跨域技术(JSONP与CROS)
    Hystrix 监控数据聚合 Turbine【Finchley 版】
    5分钟搭建网站实时分析:Grafana+日志服务实战
    idea解决打开大文件消耗CPU问题
    String类
    匿名对象,内部类和访问修饰符应用
  • 原文地址:https://www.cnblogs.com/ykgo/p/9347229.html
Copyright © 2011-2022 走看看