Django框架学习——3—(URL指定默认的参数、re_path函数、模板介绍、模板变量、常用标签)

1、URL指定默认的参数

article/views.py

from django.shortcuts import render
from django.http import HttpResponse

book = [
    "python",
    "java",
    "PHP",
]


def article(request):
    return HttpResponse("前台文章 % s" % book[0])


def page(request, page_num=1):
    return HttpResponse("前台文章第 % s 页" % page_num)

article/urls.py

# -*- encoding: utf-8 -*-
"""
@File    : urls.py
@Time    : 2020/6/19 10:13
@Author  : chen

"""
from django.http import HttpResponse
from django.urls import path
from . import views

urlpatterns = [
    path('', views.article),             # 在django_url/urls.py中绑定了路由的前缀,这里可以不写
    path('pag/', views.page),            # 无参数时默认传递page_num=1
    path('pag/<page_num>', views.page),   # 传参page_num
]

两个路由地址完成指定默认参数传递:
在这里插入图片描述
在这里插入图片描述

2、re_path函数

有时候我们在写url匹配的时候,想要写使用正则表达式来实现一些复杂的需求,那么这时候我们可以使用re_path来实现。re_path的参数和path参数一模一样,只不过第一个参数也就是route参数可以为一个正则表达式。

article/urls.py

# -*- encoding: utf-8 -*-
"""
@File    : urls.py
@Time    : 2020/6/19 10:13
@Author  : chen
article/urls.py
"""
from django.http import HttpResponse
from django.urls import path, re_path
from django.conf.urls import url    # url的源码调用的方法是re_path
from . import views

urlpatterns = [
    path('', views.article),             # 在django_url/urls.py中绑定了路由的前缀,这里可以不写
    path('page/', views.page),            # 无参数时默认传递page_num=1
    path('page/<page_num>', views.page),   # 传参page_num
    
    # 正则匹配
    re_path(r"^$", views.article),
    re_path(r"article_year/(?P<year>\d{4})$", views.article_year),        # ?P<year>  给分组取名字
    re_path(r"article_month/(?P<month>\d{2})$", views.article_month),     # ()  进行分组
]

article/views.py

from django.shortcuts import render
from django.http import HttpResponse

book = [
    "python",
    "java",
    "PHP",
]


def article(request):
    return HttpResponse("前台文章 % s" % book[0])


def page(request, page_num=1):
    return HttpResponse("前台文章第 % s 页" % page_num)


def article_year(request, year):
    return HttpResponse("年份是 % s" % year)


def article_month(request, month):
    return HttpResponse("月份是 % s" % month)

在这里插入图片描述

3、模板介绍

在之前的介绍中,视图函数只是直接返回文本,而在实际生产环境中其实很少这样用,因为实际的页面大多是带有样式的HTML代码,这可以让浏览器渲染出非常漂亮的页面。DTL是Django Template Language三个单词的缩写,也就是Django自带的模板语言。当然也可以配置Django支持Jinja2等其他模板引擎,但是作为Django内置的模板语言,和Django可以达到无缝衔接而不会产生一些不兼容的情况。

DTL与普通的HTML文件的区别

DTL模板是一种带有特殊语法的HTML文件,这个HTML文件可以被Django编译,可以传递参数进去,实现数据动态化。在编译完成后,生成一个普通的HTML文件,然后发送给客户端。

渲染模板

渲染模板有多种方式。这里讲下两种常用的方式。

  • 1.render_to_string:找到模板,然后将模板编译后渲染成Python的字符串格式。
    最后再通过HttpResponse类包装成一个HttpResponse对象返回回去。
from django.template.loader import render_to_string
from django.http import HttpResponse

def book_detail(request,book_id):
    html = render_to_string("index.html")
    return HttpResponse(html)


错误信息:django.template.exceptions.TemplateDoesNotExist: index.html
解决办法:需要在settings.py里面设置:'DIRS': [os.path.join(BASE_DIR, 'templates')],

在这里插入图片描述

  • 2.以上方式虽然已经很方便了。但是django还提供了一个更加简便的方式,直
    接将模板渲染成字符串和包装成HttpResponse对象一步到位完成。

book/views.py

from django.shortcuts import render
from django.http import HttpResponse
from django.template.loader import render_to_string


# 模板渲染绑定的两种方式
def index(request):
    # return HttpResponse("图书首页")
    html = render_to_string("index.html")
    # print(html)
    # print(type(html))                     # <class 'django.utils.safestring.SafeText'>
    return HttpResponse(html)             # 返回HttpResponse类型的html文件进行渲染


def book_detail(request):
    # 注意第一个参数request要有
    return render(request, "book_detail.html")    # render在源码中封装了render_to_string和HttpResponse

book/urls.py

# -*- encoding: utf-8 -*-
"""
@File    : urls.py
@Time    : 2020/6/20 16:19
@Author  : chen

book/urls.py
"""
from django.urls import path
from . import views


urlpatterns = [
    path('', views.index),
    path('book_detail/', views.book_detail),
]

模板查找路径配置

在项目的settings.py文件中。有一个TEMPLATES配置,这个配置包含了模板引擎的配置,模板查找路径的配置,模板上下文的配置等。模板路径可以在两个地方配置。

  • 1.DIRS:这是一个列表,在这个列表中可以存放所有的模板路径,以后在视图中使用render或者render_to_string渲染模板的时候,会在这个列表的路径中查找模板。
  • 2.APP_DIRS:默认为True,这个设置为True后,会在INSTALLED_APPS的安装了的APP下的templates文件加中查找模板。settings.py中INSTALLED_APPS数组中添加你的app名字。
  • 3.查找顺序:比如代码render(‘list.html’)。先会在DIRS这个列表中依次查找路径下有没有这个模板,如果有,就返回。如果DIRS列表中所有的路径都没有找到,那么会先检查当前这个视图所处的app是否已经安装,如果已经安装了,那么就先在当前这个app下的templates文件夹中查找模板,如果没有找到,那么会在其他已经安装了的app中查找。如果所有路径下都没有找到,那么会抛出一个TemplateDoesNotExist的异常。

在这里插入图片描述

4、模板变量

DTL模板语法

模板中可以包含变量,Django在渲染模板的时候,可以传递变量对应的值过去进行替换。变量的命名规范和Python非常类似,只能是阿拉伯数字和英文字符以及下划线的组合,不能出现标点符号等特殊字符。 变量需要通过视图函数渲染,视图函数在使用render或者render_to_string的时候可以传递一个context的参数,这个参数是一个字典类型。

book/views.py

from django.shortcuts import render
from django.http import HttpResponse
from django.template.loader import render_to_string


# 模板渲染绑定的两种方式
def index(request):
    # return HttpResponse("图书首页")
    html = render_to_string("index.html")
    # print(html)
    # print(type(html))                   # <class 'django.utils.safestring.SafeText'>
    return HttpResponse(html)             # 返回HttpResponse类型的html文件进行渲染


# 类
class Person(object):
    def __init__(self, username):
        self.username = username


def book_detail(request):
    context = {
        "username": "12345",
        "book": ["python", "java", "php"],
        "books": ("python", "java", "php"),
        "info": {
            "name": "xxxxx"
        },
        # 传递类
        "person": Person("ch")
        
    }
    # 注意第一个参数request要有   # render在源码中封装了render_to_string和HttpResponse
    return render(request, "book_detail.html", context=context)

book/book_detail.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <p>这是book_detail.html</p>
    <p>欢迎 {{ username }}</p>
    <hr>
    <!--  在html中,只能正向取值  -->
    <p>{{ book.0 }}</p>
    <p>{{ book.1 }}</p>
    <p>{{ book.2 }}</p>
    <hr>
    <p>{{ books.1 }}</p>
    <p>{{ books.2 }}</p>
    <hr>
    <!--  显示字典中的数据  -->
    <p>{{ info.name }}</p>
    <hr>
    <!--  显示类中的数据  -->
    <p>{{ person.username }}</p>
</body>
</html>

显示效果如下:
在这里插入图片描述
模板中的变量同样也支持点(.)的形式。在出现了点的情况,比如person.username,模板是按照以下方式进行解析的:

  • 1.如果person是一个字典,那么就会查找这个字典的username这个key对应的值。
  • 2.如果person是一个对象,那么就会查找这个对象的username属性,或者是username这个方法。
  • 3.如果出现的是person.1,会判断persons是否是一个列表或者元组或者任意的可以通过下标访问的对象,
    如果是的话就取这个列表的第1个值。如果不是就获取到的是一个空的字符串。

注意

不能通过中括号的形式访问字典和列表中的值,比如dict[‘key’]和list[1]是不支持的!
因为使用点(.)语法获取对象值的时候,可以获取这个对象的属性,如果这个对象是一个字典,也可以获取这个字典的值。所以在给这个字典添加key的时候,千万不能和字典中的一些属性重复。比如items,items是字典的方法,那么如果给这个字典添加一个items作为key,那么以后就不能再通过item来访问这个字典的键值对了。

5、常用标签

常用的模板标签

  • 1、 if标签:if标签相当于Python中的if语句,有elif和else相对应,但是所有的标签都需要用标签符号({%%})进行包裹。if标签中可以使用==、!=、<、<=、>、>=、in、not in、is、is not等判断运算符。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <p>这是模板文件html</p>
    <hr>

    {% if age > 18 %}
        <p>您是成年人了</p>
    {% elif age == 18 %}
        <p>您刚满18岁</p>
    {% else %}
        <p>您是未成年人</p>
    {% endif %}

    {% if "张三" in persons %}
        <p>张三</p>
    {% else %}
        <p>李四</p>
    {% endif %}
</body>
</html>
  • 2、for…in…标签:for…in…类似于Python中的for…in…。可以遍历列表、元组、字符串、字典等一切可以遍历的对象。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
	{% for book in books %}
	    <p>{{ book }}</p>
	{% endfor %}
	
	<!--  在html中,反向遍历   --> 
	{% for book in books reversed %}
	    <p>{{ book }}</p>
	{% endfor %}
</body>
</html>
  • 3、遍历字典的时候,需要使用items、keys和values等方法。在DTL中,执行一个方法不能使用圆括号的形式。
<!--  for key,value in person.keys   --> 
{% for key,value in person.items %}
    <p>key:{{ key }}</p>
    <p>value:{{ value }}</p>
{% endfor %}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章