django 静态文件(static)+模板函数(template)+中间件

目录

1、静态文件(static)

2、2静态文件查找顺序

2.3 媒体文件

2、模板

2、1模板寻找路径配置

2、2模板处理的本质

2、3 创建自定义函数文件夹

2、4母板和子版

2、5导入母板

3、将数据库的时间转换为自定义格式

4、中间件

4.1中间件配置

4.2 MiddlewareMixin(建议)

4、3疑问:prcess_request的执行时,是否已执行了路由匹配?

4、4中间件执行顺序

4、5小结

5、中间件执行顺序


1、静态文件(static)

开发需要:css、js、图片。

- 根目录的 /static/
- 已经app目录下载 /static/ 文件夹下        

媒体文件:用户上传的数据(excel/pdf/video)

- 根目录的 /media/

1、静态文件的目录结构

/static/js/XXX
/static/css/xxx
/static/images/xxx
/static/plug/js/XXX/
/static/plug/css/xxx
/static/plug/images/xxx

  2、静态文件的配置


INSTALLED_APPS = [
    # 'django.contrib.admin',
    # 'django.contrib.auth',
    # 'django.contrib.contenttypes',
    # 'django.contrib.sessions',
    # 'django.contrib.messages',
    'django.contrib.staticfiles',
    "apps.api.apps.ApiConfig",
    "apps.web.apps.WebConfig",
]
...
STATIC_URL = '/static/' #在模板中调用static函数时,会自动帮你在路径前补全'/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)#(静态文件首先寻找的路径)

3、很重要:便于理解在模板中调用static函数方法

STATIC_URL = '/static/'
 #在模板中调用static函数时,会自动帮你在路径前补全'/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
#(静态文件首先寻找的路径)

2、2静态文件查找顺序

    1、默认先去settings.STATICFILES_DIRS指定的路径找。(公共)
    2、-   按注册顺序每个已注册的app中找他static目录,去这个目录中寻找静态文件
    3、 -   一般情况下,原则,那个app中的的模板,去哪个那个app中寻找。

    4、多app开发:各自app的图片放在各自 /static/app名字/。。。

在开发过程中(模板中)

#1、禁止
<img src="/static/api/1.png">

#2、
{% load static %}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>登录页面</h1>
<a href="/xxx/xxxxx/">调换dao xx</a>
<a href="{% url 'login' %}">跳转</a>

<img src="{% static 'api/1.png' %}">

</body>
</html>

2.3 媒体文件

from django.contrib import admin
from django.urls import path, re_path, include
from django.conf.urls.static import static
from django.conf import settings

from apps.api import views


# 很多功能,很多URL
urlpatterns = [
    path('api/', include('apps.api.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

2、模板

2、1模板寻找路径配置

TEMPLATES = [
    {	
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                # 'django.contrib.auth.context_processors.auth',
                # 'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

1、优先去项目根目录 > 每个已注册的app的templates目录找。

2、如何选择:

  • 简单的项目,模板都放在根目录。

  • 复杂的项目,模板放在各自的app中,公共部分放在templates目录。

扩展:修改内置app的模板也是同样的套路。

2、2模板处理的本质

渲染完成后,生成了字符串,再返回给浏览器。

先替换在把完整的字符串返回给浏览器

2、3 创建自定义函数文件夹

想要使用自定义模板函数的话需要先创建用于存放函数的文件夹,而在django中对于自定义函数文件夹的名称有严格的要求,即要求存放自定义模板函数的文件夹必须叫templatetags

  • 首先在项目根目录中创建templatetags文件夹
  • 创建模板函数py文件,文件名可自定义,笔者这里叫utils.py
    templatetags/utils.py
from django import template
from django.utils.safestring import mark_safe
 
register =template.Library()

自定义函数一般有三种:

1、一种是filter,这个最多只能传递两个参数,可作为if条件使用

- 数据处理,参数:1~2个
- 数据处理,if条件

from django import template

register = template.Library()
@register.simple_tag
def add(a,b):
    return a+b



#模板调用方式
<p>{% 2|add:3 %}</p>
#第一个参数 | 函数名:第二个参数

2、一种是simple_tag,这种不会限制参数的个数,但是不能作为IF的条件来使用,参数无限制 & 返回文本返回什么就展示什么

from django import template

register = template.Library()    
@register.simple_tag
def mytag1(a,b):
    return a+b


#模板调用demo
<p>{% mytag1 %}</p>
<p>{% mytag2 "太卡了" "终于不用听了" %}</p>

3、一种是inclusion_tag,,参数无限制 & HTML片段

@register.inclusion_tag('left_tag.html')
def left_panel(username):
    user_obj = models.UserInfo.objects.filter(username=username).first()
    blog = user_obj.blog
    # 文章分类
    category_article_list = models.Category.objects.filter(blog=blog).annotate(num=Count('article')).values('title',                                                                                                       'num')
    # 标签分类
    tag_article_list = models.Tag.objects.filter(blog=blog).annotate(num=Count('article')).values('title', 'num')
    # 时间分类auth_group
    time_archive_list = models.Article.objects.filter(user__username=username).extra(
        select={'ym': 'DATE_FORMAT(create_time,"%%Y-%%m")'}
    ).values('ym').annotate(num=Count('nid')).values('ym', 'num')
 
    return {
        'username': username,
        'category_article_list': category_article_list,
        'tag_article_list': tag_article_list,
        'time_archive_list': time_archive_list,
    }

2、4母板和子版

公共的内容放入母板中(根目录下的template文件下)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="公共css文件">
    {% block css %}{% endblock %}
</head>
<body>
<h1>头部</h1>
{% block body %}{% endblock %}
<h1>尾部</h1>


<script src="公共js文件 "></script>
{% block js %}{% endblock %}
</body>
</html>

2、5导入母板

{% extends 'layout.html' %}
{% block css %}

{% endblock %}

{% block body %}
    <h1>主页</h1>

    {% include "app01/header.html" %}

    <p>{{ info }}</p>

    {% verbatim %} #不会替换,一般没有意义
        <p>{{ info }}</p>
    {% endverbatim %}


{% endblock %}


{% block js %}

{% endblock %}

3、将数据库的时间转换为自定义格式

<h2>{{ n9|date:"Y-m-d H:i:s" }}</h2>

4、中间件

4.1中间件配置

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    # 'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    # 'django.contrib.auth.middleware.AuthenticationMiddleware',
    # 'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'middlewares.md.MyMd1',
    'middlewares.md.MyMd2',
    'middlewares.md.MyMd3',
]

1、中间件从上按顺序往下执行

4.2 MiddlewareMixin(建议)

from django.shortcuts import HttpResponse
from django.utils.deprecation import MiddlewareMixin


class MyMd1(MiddlewareMixin):
    def process_request(self, reqeust):
        print("md1来了")

    def process_view(self, request, view_func, view_args, view_kwargs):
        # print(request, view_func)
        print("view 1")

    def process_response(self, request, response):
        print('md1走了')
        return response

    def process_exception(self, request, exception):
        # 视图函数,抛出异常
        print("异常了", exception)
        return HttpResponse("异常了")

    def process_template_response(self,request,response):
        # 在视图函数中,返回的是TemplateResponse对象;     render方法
        # response.render()
        return response

1、建议继承MiddlewareMixin,不要用原始方法

2、中间件会自动调用__call__方法

class MyMd(object):
    def __init__(self....):
        pass
    
    def __call__(self,....):
        pass
        
django内部默认执行call方法,传入参数。

默认执行call方法

class MiddlewareMixin:
    def __init__(self, get_response=None):
        self.get_response = get_response
        
    def __call__(self, request):
        response = None
        if hasattr(self, 'process_request'):
            response = self.process_request(request)
            response = response or self.get_response(request)
        if hasattr(self, 'process_response'):
            response = self.process_response(request, response)
        return response
    
    
class MyMd(MiddlewareMixin):
    
    def process_request(self,request):
        ...
    
    def process_response(self,request, response):
        ...
    
django内部默认执行call方法,传入参数。

4、3疑问:prcess_request的执行时,是否已执行了路由匹配?

1、prcess_request的执行时,没有已执行了路由匹配,即:request.resolver_match为none

2、prcess_view的执行时,已执行了路由匹配,即:request.resolver_match为当前路由信息

4、4中间件执行顺序

1、先执行prcess_request,在执行prcess_view

2、prcess_request的执行时,有return时,后面的中间件不执行prcess_request,prcess_response从prcess_request的执行时return的中间件开始执行

3、prcess_view的执行时,有return时,后面的中间件不执行prcess_view,prcess_response从最后一个中间件往前执行(全部执行)

4、5小结

  • 定义中间类

  • from django.shortcuts import HttpResponse
    from django.utils.deprecation import MiddlewareMixin
    
    
    class MyMd1(MiddlewareMixin):
        def process_request(self, reqeust):
            print("md1来了")
    
        def process_view(self, request, view_func, view_args, view_kwargs):
            # print(request, view_func)
            print("view 1")
    
        def process_response(self, request, response):
            print('md1走了')
            return response
    
        def process_exception(self, request, exception):
            # 视图函数,抛出异常
            print("异常了", exception)
            return HttpResponse("异常了")
    
        def process_template_response(self,request,response):
            # 在视图函数中,返回的是TemplateResponse对象;     render方法
            # response.render()
            return response

  • 类方法

    • process_request

    • process_view

    • process_reponse

    • process_exception,视图函数出现异常,自定义异常页面。

    • process_template_response,视图函数返回TemplateResponse对象 or 对象中含有.render方法。

5、中间件执行顺序

1、多个中间件时,process_view是在所有的process_request执行完,在从前往后执行process_view

2、process_request执行过程中return返回时,process_view一个不执行,从当前对象的process_reponse往前执行

3、process_view执行过程中return返回时,从最后一个process_reponse往前执行

4、执行process_view时一定保证process_request都没有问题

5、process_request没有路由信息,process_view有路由信息

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值