Django模板层介绍又大又全又好记

一、MTV和MVC

1 django 是MTV架构,本质也是mvc
	-M:model,数据库相关操作
    -T:template,模板文件(就是mvc的v层)
    -V:view,视图(urls+view=MVC的控制器)
2 MVC架构:主流的web框架都是mvc
	-Web应用分为模型(M),控制器(C)和视图(V)
    -M:model,数据库相关操作
    -C:controler控制器,逻辑相关,逻辑代码
    -V:视图,模板文件

在这里插入图片描述

二、Django的请求生命周期

在这里插入图片描述

三、有名分组和无名分组

#  re模块演示
import re


res = re.search('([0-9]{4})/([0-9]{2})', '2020/10')
print(res.group[1])  =======>  2020  # 注意这里的起始位置是1
print(res.group[2])  =======>  10

res = re.search('(?P<year>[0-9]{4})/(?P<month>[0-9]{2})', '2020/10')
print(res.group('year'))	=======>  2020
print(res.group('month'))	=======>  10


#1 无名分组的使用
    ### 无名分组,把分组分出来的值,当作位置参数传递给视图函数
    url(r'^login/([0-9]{4})/([0-9]{2})', views.login),
#2 有名分组的使用
    ### 有名分组,把分组出来的值,当作关键字参数传递给视图函数
    url(r'^login/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})', views.login),
    (127.0.0.1:8000/login/2020/10)
        def login(request, year, month):
             print(year)	=======>  2020
             print(month)	=======>  10
             return HttpResponse('login')

            
#3  有什么作用
	可以从url地址中解析出参数,传递给视图函数使用
    
#4  案例
    # 这种地址,把人名和id分出来
    # 有名分组
    # ilovejaney/p/13748739.html
    url(r'^(?P<name>.*?)/p/(?P<num>\d+).html', views.article),
    # 无名分组
    url(r'^(.*?)/p/(\d+).html', views.article),
  
def article(request, name, num):
     print(name)
     print(nim)
     return HttpResponse('你的名字是%s,你的文章num是%s'%(name,num))


# 5 伪静态
	-原来是动态页面/login   做成/login.html  伪装成静态页面,便于seo优化
	-seo优化:
	-https://www.cnblogs.com/w/articles/9509792.html
    

四、路由的分发

1 有一个总路径,根路由,总路由负责做分发
2 每个app有自己的路由和视图函数的对应关系

3 使用:
	-1 在根路由中配置
        # 路由分发
        # 第一种方式
        from django.conf.urls import url, include
        
        url(r'^app01', include('app01.urls')),
        url(r'^app02', include('app02.urls')),
        
        # 第二种方式
        from app01 import urls
        url(r'^app01',include(urls)),
    -2 在不同app中新建urls.py
    from . import views
    	urlpatterns = [
            url(r'/login/', views.login), 
            url(r'/home/', views.home),
        ]
    -3 http://127.0.0.1:8000/app01/login/  
            先匹配app01,如果成功分发到app01的urls中继续匹配

五、反向解析

1 通过路由的别名,动态的解析出路由的地址


urlpatterns = [
            url(r'/login/', views.login),  
           # url(r'/home/', views.home, name='home'),
            url(r'/aaaaaaa/', views.home, name='home'),
        ]

2 用在视图函数中:
from django.shortcuts import render, HttpResponse, redirect, reverse

def login(request):
	url = reverse('home')  # home就是路由的别名
     print(url)  ====>'/aaaaaa/'
    
3 模板文件中使用
	{% url 'home' %}
    
4 有什么作用
	-动态根据路由别名获得路径,一旦路径改变,不需要改其他代码
	

六、名称空间

#  示例:
总路由:
     url(r'^app01',include('app01.urls') ),
     url(r'^app02',include('app02.urls') ),

app01:
urlpatterns = [
            url(r'/login/', views.login,name='login'),  
            url(r'/home/', views.home, name='home'),
        ]

app02:
urlpatterns = [
            url(r'/login/', views.login,name='login'),  
            url(r'/home/', views.home, name='home'),
        ]

      {% url 'home' %}   # 只会解析出app02中的,总路由中后配置的

1 路由做反向解析时,如果有同名路由,出现问题
2 在做路由分发时,给每个app的路径设置一个名称空间

3 使用步骤
	-1 在总路由中设置
    	url(r'^app01',include('app01.urls',namespace='名称空间的名字') ),
        
	-2、分路由中
     url(r'/home/', views.index,name='home'),

    -3 用在视图函数中:
        url=reverse('名称空间的名字:home')  # home就是路由的别名
        print(url)
        
    -4 模板文件中使用
        {% url '名称空间的名字:home' %}

七、path中的转换器

1 5个内置转换器
'''
    str,匹配除了路径分隔符(/)之外的非空字符串,这是默认的形式
    int,匹配正整数,包含0。
    slug,匹配字母、数字以及横杠、下划线组成的字符串。
    uuid,匹配格式化的uuid,如 075194d3-6885-417e-a8a8-6c931e272f00。
    path,匹配任何非空字符串,包含了路径分隔符(/)(不能用?)
'''

2 例子
	-path('login/<int:year>', views.login),
    -path('login/<str:year>', views.login),
    -path('login/<path:p>', views.article),
3 高级例子
	-实现匹配这种路径:http://127.0.0.1:8000/liuqingzheng/p/4444.html
    -path('<str:name>/p/<int:id>.html', views.article),
    -re_path(r'^(?P<name>.*?)/p/(?P<id>\d+).html$', views.login),
    -url(r'^(?P<name>.*?)/p/(?P<id>\d+).html$', views.login),  
    # url在2.x以后不建议使用
    
    
    
4 转换器可以不可以在re_path中使用?不能!!!!

八、自定义的转换器

1 写一个类
	-regex属性:这里写的正则表达式就能匹配
    -to_python方法
    -to_url 方法
    
2 在settings.py中注册这个类
	register_converter(类名, 转化器名字)  
    
3 在path中使用
	path('<lqz:name>/', views.article),



class FourDigitYearConverter:  
    regex = '[0-9]{4}'  
    def to_python(self, value):  
        return int(value)  
    def to_url(self, value):  
        return '%04d' % value    
    
    
from django.urls import register_converter, path  
from . import converters, views  
register_converter(converters.FourDigitYearConverter, 'yyyy')  
urlpatterns = [  
    path('articles/2003/', views.special_case_2003),  
    path('articles/<yyyy:year>/', views.year_archive),  
    ...  
]

九、Django请求对象

def index(request):
    '''
    request:django封装的对象,它的类是WSGIRequest,它里面包含了所有http请求的东西
    '''
    print(request)
    print(type(request))
    # from django.core.handlers.wsgi import WSGIRequest
    #######################1
    print(request.method)
    print(request.GET)
    print(request.POST)

    ########################2 path,get_full_path,META,FIELS,body
    # 自定制请求头
    # 上传文件使用的编码方式是form-data,默认编码方式urlencoded
    print(request.is_ajax()) # 是不是ajax请求
    print(request.path)      # 请求路径
    print(request.get_full_path()) # 请求全路径,带数据

    # print(request.body)      # 请求体,二进制,如果传文件,这个报错
    '''
    使用form表单,默认情况下数据被转成name=wuxi&password=123放到请求体中
    request.POST其实是从body中取出bytes格式的,转成了字典,如果不是用&连接的,POST取不出来
    requet.GET其实是把路径中?后面的部分拆出来,转成了字典
    '''
    print(request.encoding) # 客户端向服务端传递时,使用的编码方法

    print(request.META)    #字典,一堆东西,请求用户的ip地址,请求头中数据,用户自定制请求头的数据
    '''
    把请求头的key值部分统一加HTTP_  并且全部转成大写
    '''
    print(request.META['REMOTE_ADDR'])  # 客户端的ip地址
    print(request.FILES)  # 客户端上传的文件


    request.META

   一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例:
  取值:

    CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。
    CONTENT_TYPE —— 请求的正文的MIME 类型。
    HTTP_ACCEPT —— 响应可接收的Content-Type。
    HTTP_ACCEPT_ENCODING —— 响应可接收的编码。
    HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。
    HTTP_HOST —— 客服端发送的HTTP Host 头部。
    HTTP_REFERER —— Referring 页面。
    HTTP_USER_AGENT —— 客户端的user-agent 字符串。
    QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。
    REMOTE_ADDR —— 客户端的IP 地址。
    REMOTE_HOST —— 客户端的主机名。
    REMOTE_USER —— 服务器认证后的用户。
    REQUEST_METHOD —— 一个字符串,例如"GET""POST"。
    SERVER_NAME —— 服务器的主机名。
    SERVER_PORT —— 服务器的端口(是一个字符串)。
   从上面可以看到,除 CONTENT_LENGTH 和 CONTENT_TYPE 之外,请求中的任何 HTTP 首部转换为 META 的键时,
    都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_  前缀。
    所以,一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键。
    
    

    ########################3 
    print(request.COOKIES) # 空字典
    print(request.session) # session对象
    print(request.user)    # 匿名用户
    return HttpResponse('ok')

十、视图层之响应对象

from django.http import JsonResponse

def index(request):
    # 三件套
    # return HttpResponse('ok')
    # return render(request,'index.html',context={'name':'wuxi','age':18})
    # return redirect('/home') # 重定向自己的地址,重定向第三方地址,经常跟反向解析一起使用

    # 向客户端返回json格式数据
    # import json
    # res=json.dumps({'name':'吴','age':18},ensure_ascii=False)
    # return HttpResponse(res)
    # django内置提供的JsonResponse
    # 本质还是HttpResponse

    # ensure_ascii
    源码部分:
    def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
                 json_dumps_params=None, **kwargs):
    	data = json.dumps(data, cls=encoder, **json_dumps_params)
    
    # return JsonResponse({'name':'w','age':18},json_dumps_params={'ensure_ascii':False})  
    **将其拆包成ensure_ascii=False
    # safe,转换除字典以外的格式,需要设置safe=False
    return JsonResponse([13,'wuxi',[1,2,3],{'name':'wuxi','age':19}],safe=False, json_dumps_params={'ensure_ascii':False})

十一、CBV和FBV

# CBV基于类的视图(Class base view)和FBV基于函数的视图(Function base view)

# 写视图类(还是写在views.py中)
## 第一步,写一个类,继承View
from django.views import View

class Index(View):
    def get(self, request):  # 当url匹配成功,get请求,会执行它
        return HttpResponse('ok')

    def post(self,request):
        return HttpResponse('post')
    
## 第二步:配置路由(django3.x版本)
path('index/', views.Index.as_view()),  # 加括号

十二、form表单文件上传,提交地址

## html注意编码方式
<form action="/index/" method="post" enctype="multipart/form-data">

    <p>用户名:<input type="text" name="name"></p>
    <p>密码:<input type="password" name="password"></p>
    <p><input type="file" name="myfile"></p>
    <p><input type="submit" value="提交"></p>
</form>

# views.py
def index(request):
    file=request.FILES.get('myfile')
    # 打开一个空文件,写入
    with open(file.name,'wb') as f:
        for line in file.chunks():
            f.write(line)
    return HttpResponse('文件上传成功')




# action
#1 不写,默认向当前地址发送请求
#2 /index/,向当前域(http://127.0.0.1:8000/)的/index/发送请求
#3 http://127.0.0.1:8000/index/,向该地址发送请求(可以向第三方服务发送请求)

# method
# 1 post:发送post请求(默认编码情况下:以key=value&key=value的形式拼到请求体中)
# 2 get:发送get请求(以key=value&key=value的形式拼到路径中)
<form action="/index/" method="post">

    <p>用户名:<input type="text" name="name"></p>
    <p>密码:<input type="text" name="password"></p>
    <p><input type="submit" value="提交"></p>
</form>

十三、前后端交互的编码方式

1 urlencoded---->传普通的数据,form表单默认就是这种---->request.POST
2 form-data-----》传文件和数据                  ---->request.POST   request.FILES
3 json----------》传json格式数据                ---->request.body中取出来自行处理

def index(request):
    # 接收urlencoded编码
    body体中:name=wuxi&age=18
    # print(request.POST)

    # 接收form-data编码
    body体中:分两部分,一部分是数据,一部分是文件
    数据部分:name=wuxi&age=18
    ---asdfasdfasdfgasgasgd---
    文件部分(二进制)
    
    #数据部分
    # print(request.POST)
    # #文件部分
    # print(request.FILES)

    # 接收json格式(通过posman发送json格式的数据)
    body体中 
    {
    "name": "wuxi",
    "age": 18
	}
    # 这里没有
    print(request.POST)
    # 数据在这(自行处理)
    print(request.body)
    res = json.loads(request.body)  # python3.6之后,json可以直接反序列化byte
    return HttpResponse('ok')

十四、Django模板语法的使用

#  方式一:
now_date = datetime.datetime.now()
return render(request, 'index.html', context={'cdate': str(now_date)})

#  方式二:(页面静态化,提高网站并发量)
with open('index.html', mode='rt', encoding='utf-8') as f:
    res = f.read()
t = Template(res)
c = Context({'cdate': str(now_date)})
html = t.render(c)	# html是渲染后的字符串
return HttpResponse(html)
DTL:Django Template Language


1 模板中使用 {{ python变量 }}

############views.py
def index(request):
    num = 10
    ss = 'w is handsome'
    b = False
    ll = [1, 2, 43]
    dic = {'name': 'w', 'age': 18}

    def test():
        print('我是test')
        return 'test return'

    class Person():
        def __init__(self, name):
            self.name = name

        def print_name(self):
            return self.name
        def __str__(self):
            return self.name

    p = Person('w')

    # return render(request, 'index.html', context={'num':num,'ss':ss,'b':b})
    #locals() 把当前作用域下所有的变量,都传到context中
    return render(request, 'index.html',locals())
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ ss }}</title>
</head>
<body>

<h1>模板语法之变量</h1>

<p>数字:{{ num }}</p>
<p>字符串:{{ ss }}</p>
<p>布尔:{{ b }}</p>
<p>列表:{{ ll }}</p>
<p>字典:{{ dic }}</p>
<p>函数:{{ test }}</p>
<p>对象:{{ p }}</p>

</body>
</html>

十五、模板语法之深度查询句点符

from django.utils.safestring import mark_safe

def index(request):
    num = 10
    ss = 'wuxi is handsome'
    b = False
    ll = [1, 2, 43, {'name': 'wen'}]
    dic = {'name': 'wuxi', 'age': 18}

    def test():
        print('我是test')
        return 'test----'

    class Person():
        def __init__(self, name):
            self.name = name

        def print_name(self):
            return self.name

        def __str__(self):
            return self.name

    p = Person('w')

    link1 = '<a href="https://www.baidu.com">点我<a>'

    link2 = mark_safe(link1)

    input_1 = '<p>用户名:<input type="text" name="name"></p>'
    input_2 = mark_safe(input_1)


    script_1='''
    <script>
    alert('你被攻击了')
    </script>
    '''
    script_2 = mark_safe(script_1)
    return render(request, 'index.html', locals())
<h2>模板语法之句点符的深度查询</h2>
<p>列表的第一个元素:{{ ll.1 }}</p>
<p>字典的name对应的值:{{ dic.name }}</p>
<p>列表的第三个元素的name对应的值:{{ ll.3.name }}</p>
<p>函数执行,直接写函数名即可:{{ test }}</p>
<p>函数如果有参数?不支持</p>
<p>对象调用方法: {{ p.print_name }}</p>
<p>对象调用属性: {{ p.name }}</p>
<hr>
<a href="https://www.baidu.com">点我</a>
<p>a标签的字符串: {{ link1 }}</p>
<p>a标签的字符串,显示成a标签: {{ link2 }}</p>

<p>用户名:<input type="text" name="name"></p>
<p>input标签:{{ input_1 }}</p>
<p>input标签,显示成标签:{{ input_2 }}</p>

<p>js原封不动显示:{{ script_1 }}</p>

{{ script_2 }} 显示为js代码
from django.utils.safestring import mark_safe
link1 = '<a href="https://www.baidu.com">点我<a>'
link2 = mark_safe(link1)

{link1|safe}

十六、模板语法之过滤器

1 {{ 参数1|过滤器名字:'参数2' }}
  {#注意:冒号后面不能加空格#}
2 过滤器最多传两个值,最少一个值  {{'w is'|slice:'2:3'}}


# 了解
{#如果变量为空,设置默认值,空数据,None,变量不存在,都适用#}
<p>{{ name |default:'数据为空' }}</p>
    
<p>过滤器之filesizeformat:{{ num|filesizeformat }}</p>
    
ss = 'w is handsome'
<p>过滤器之slice{{ ss|slice:"7:11" }}</p>
    
第二个参数写012, 都是 ...,  最少从3开始
<p>过滤器之truncatechars:{{ ss|truncatechars:'30' }}</p>
<p>truncatewords:{{ ss|truncatewords:'2' }}</p>
# 记住
<p>过滤器之date:{{ ctime|date:'Y年m月d日-------H时i分s秒' }}</p>
<p>过滤器之safe:{{ link1|safe }}</p>

{#add   可以加负数,传数字字符串都可以#}
 <p>{{ "10"|add:"-2" }}</p>
  
    

{#upper#}
<p>{{ name|upper }}</p>
<p>{{ 'WW'|lower }}</p>

十七、标签

1 {% 标签名 %}


2 标签for  ,在标签for的内部一直有一个forloop对象,是个字典
counter0:从0开始,每循环一次加1
counter:从1开始,每循环一次加1
revcounter:从列表长度开始,每循环一次减一
first:判断是不是循环的第一个
last:判断是不是循环的最后一个
parentloop:父级forloop对象(for循环嵌套)
{'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 6, 'revcounter0': 5, 'first': True, 'last': False}

3 if标签
# views.py
def index(request):
    ll = ['w','u','x','i','nb']
    # ll = []
    dic = {'name':'w','age':19}
    count = 1

    wisnbplus = 'w'
    # b = False
    b = True
    user_list = [{'name':'w','age':19},{'name':'u','age':18},{'name':'x','age':22},{'name':'i','age':99},{'name':'n','age':18},{'name':'b','age':18}]
    return render(request, 'index.html', locals())
#index.html
<h1>模板语法之标签</h1>

<h2>for的用法</h2>
{% for l in ll %}
    <p>{{ l }}</p>
    <p><a href="http://127.0.0.1:8080/{{ l }}">{{ l }}</a></p>
{% endfor %}

<hr>
{% for k,v in dic.items %}
    <p>key值为:{{ k }} , value值为{{ v }}</p>
{% endfor %}

<table border="1">
    <tr>
        <td>id号</td>
        <td>用户名</td>
        <td>年龄</td>
    </tr>
    {% for dic in user_list %}
        <tr>
            <td>{{ forloop.counter }}</td>
            <td>{{ dic.name }}</td>
            <td>{{ dic.age }}</td>
        </tr>
    {% endfor %}

</table>

<hr>
<h2>for ----empty的用法</h2>
<ul>
    {% for l in ll %}
        <li>{{ l }}</li>
    {% empty %}
        <li>没有数据</li>
    {% endfor %}
</ul>

<h2>forloop对象</h2>
{% for dic in user_list %}

    {% for key,value in dic.items %}
        {{ forloop.parentloop.counter }}  # 获得父级counter编号
        <p>{{ key }}:{{ value }}</p>
    {% endfor %}

{% endfor %}

<h2>if</h2>

{% if b %}
    <p>b是true的</p>
{% else %}
    <p>b是false的</p>
{% endif %}


<h2>with重命名</h2>


{% with forloop.parentloop.counter as aaa %}
    {{ aaa }}
{% endwith %}


{% with wisnbplus as a %}
{{ a }}
----{{ wisnbplus }}

{% endwith %}


<h2>csrf</h2>

{% csrf_token %}
<input type="hidden" name="csrfmiddlewaretoken" value="uC35XuP1J2Va74ArYiNw4TMZ0PaZ6V4qvVGCsUQcqiKF5Sr8IrWS0rzpmOmPBrjY">
</body>

十八、自定义标签和过滤器

	-第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
    -第二步:在app中创建templatetags包(包名只能是templatetags,不能改)
    -第三步:在包内,新建py文件(如:my_tags.py)
    -第四步:写代码(过滤器)
    	from django import template
        register = template.Library()
        @register.filter
        def my_upper(value):
            return value.upper()
    -第五步使用:(模板),先load,再使用
    	{% load my_tags %}
		{{ 'aa'|my_upper }}




# 可以生成一片模板中的代码块
# 使用:5步
	-第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
    -第二步:在app中创建templatetags包(包名只能是templatetags,不能改)
    -第三步:在包内,新建py文件(如:my_tags.py)
    -第四步:写代码(inclusion_tag)
  	# inclusion_tag,传一个模板文件
    
    1、在my_tags.py中
    @register.inclusion_tag('left.html')
    def left(num):
        # dic={0:第0页,1:第1页,2:第2页}
        dic = {i: '第%s页' % i for i in range(num)}
        # 固定返回的必须是字典
        print(dic)
        return {'data': dic}

    @register.inclusion_tag('beautiful.html')
    def beautiful(title, url):
        return {'title': title, 'url': url}
    
    2、在left.html中
    {% for key,value in data.items %}
    <p>key是:{{ key }}   value是:{{ value }}</p>
	{% endfor %}

    -第五步使用:在index.html中,先load,再使用
    
    	{% load my_tags %}
		{% left 5%}
        {% beautiful '名字' '地址'%}
        
        
# 它跟tag有什么不同?
	-tag需要再代码中写html的东西
    -inclusion_tag代码跟模板分离



### 通过tag实现beautiful的功能
@register.simple_tag
def tab_beautiful(title, url):
    return mark_safe('''
    <div class="panel panel-danger">
    <div class="panel-heading">
        <h3 class="panel-title">%s</h3>
    </div>
    <div class="panel-body">
        详情点击:<a href="%s">疯狂点我</a>
    </div>
</div>
    ''' % (title, url))
	-第一步:在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag
    -第二步:在app中创建templatetags包(包名只能是templatetags,不能改)
    -第三步:在包内,新建py文件(如:my_tags.py)
    -第四步:写代码(过滤器)
    	from django import template
        from django.utils.safestring import mark_safe
        register = template.Library()
        @register.simple_tag
        def my_csrf():
            import uuid
            res=uuid.uuid4()
            return mark_safe('<input type="hidden" name="csrfmiddlewaretoken" value="%s">'%res)
        @register.simple_tag
		def my_tag(value):
    		return value.isupper()
    -第五步使用:(模板),先load,再使用
    	{% load my_tags %}
		{% my_tag %}
        {% my_tag 'WU'  %}  

十九、模板的应用和继承

-第一步:新建一个 xx.html,把好看的模板写入


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js'></script>
    <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <script src='https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js'></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="panel panel-danger">
            <div class="panel-heading">
                <h3 class="panel-title">花开花落花满天</h3>
            </div>
            <div class="panel-body">
                详情点击:<a href="http://www.baidu.com" target="_blank">红消香断有谁怜</a>
            </div>
        </div>
    </div>
</div>
</body>
</html>
    

-第二步:再你想用的地方


{% include 'test1.html' %}  # 引入!!!!!!!!!!!!!!!


-第一步:写一个母版,写空盒子
	   {% block top %}  # 写在需要添加内容的位置
        
        {% endblock %}
-第二步:某个页面要使用母版,引入,扩写盒子
	{% extends 'base.html' %}
    {% block top %}
		index页面
	{% endblock %}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二十、静态文件的连接

第一种: <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">



第二种:
    {% load static %}
    <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">



第三种:
    {% load static %}
	<link rel="stylesheet" href="{% get_static_prefix %}bootstrap/css/bootstrap.min.css">



# 特殊用法(注意:若A.html继承其他母版时,需要写在母版中,方可在A.html使用)
	{% load static %}
    {% static "images/hi.jpg" as myphoto %}
    <img src="{{ myphoto }}" alt="Hi!">
    
    {% load static %}
	{% get_static_prefix as static %}
	<img src="{{ static }}images/hi.jpg" alt="Hi!" />

例子:
# 母版
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    {% load static %}
    {% get_static_prefix as ssstatic %}
    <script 
</head>


# A.html
<body>
    {% block top %}
        <h1>一笑倾城</h1>
    	<img src="{{ ssstatic }}img/pexels-pixabay-416676.jpg" alt="chonglang" title="冲浪" style="width: 400px">
    {% endblock %}

</body>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于Django的模型、视图和模板,我可以做个简单的介绍Django是一个MVC框架,其中的M、V、C分别指的是模型、视图和控制器(其中控制器Django对应的是URLconf),而这里的MVC与传统的MVC有所不同,更倾向于MVT的架构,即模型(Model)、视图(View)和模板Template)。 - 模型(Model):模型主要是把应用中需要用到的数据以类似面向对象的方式进行定义、管理和操作,通常对应database中的表。Django中的ORM(Object-relational mapping)对开发者屏蔽了底的SQL操作,开发者可以直接以Python语言去操作数据库,而不需要关心底SQL的实现细节。 - 视图(View):视图最主要的作用是处理用户的请求,响应相应的结果给用户。一般来说,视图会从数据库、缓存等数据源中获取数据,然后将结果进行组装,返回HttpResponse给用户。Django中视图可以通过函数或者类的方式来定义,对外提供一个可被URLconf调用的可调用对象。 - 模板Template):模板是视图生成响应结果的主要组成部分,可以理解为一个动态生成的HTML页面,其中包含了数据展示、控制逻辑、页面渲染等元素。Django中的模板提供了超过100个内置的指令和过滤器,开发者可以非常方便的实现模板的渲染和页面的实现。 总结一下,模型主要和数据打交道,视图主要和操作和生成Http Response联系在一起,模板主要负责页面的渲染和数据展示。希望这个介绍可以帮到你。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值