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 %}