模型的Objects
獲取或操作模型的對(duì)象
1. views.py
要怎么寫(xiě)
在第三課創(chuàng)建好應(yīng)用后剿另,打開(kāi)應(yīng)用目錄顯示如下:
其中似芝,templates
文件夾和urls.py
是我后創(chuàng)建的。其他都是一開(kāi)始就有的晕城。
在經(jīng)過(guò)上節(jié)課一番折騰后除盏,我們來(lái)到了寫(xiě)views.py
的環(huán)節(jié)噩斟。這次views.py
是已經(jīng)自帶了阳欲,不需要手動(dòng)創(chuàng)建。初始代碼如下:
# views.py
from django.shortcuts import render
# Create your views here
除了import
了一個(gè)模塊之后便再無(wú)其他內(nèi)容毡咏。需要我們手寫(xiě)驮宴。
先去models.py
定義model
如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from django.db import models
# Create your models here.
class Article(models.Model): # 從models中找字段類型
title = models.CharField(max_length = 30)
content = models.TextField()
然后回到views.py
,重新定義:
from django.shortcuts import render
from .models import Article
from django.http import HttpResponse
# Create your views here
def article_detail(request, article_id):
article = Article.objects.get(id = article_id)
return HttpResponse("文章內(nèi)容是{} <br> 標(biāo)題是{}".format(article.title, article.content))
這樣一來(lái)呕缭,我們就可以在頁(yè)面中顯示文章內(nèi)容與標(biāo)題了堵泽。但由于Django是后端框架,這樣寫(xiě)反而是前后端代碼混一起了恢总,違背了我們“前后端分離”的原則迎罗,所以怎樣把前端代碼從后端中剝離出來(lái)呢?
首先片仿,新建templates
文件夾纹安,用于存放html代碼。這是Django固定語(yǔ)法,不要叫別的名字厢岂。
然后光督,根據(jù)實(shí)際情況建立對(duì)應(yīng)的html文件。比如咪笑,顯示文章細(xì)節(jié)可帽,則需要article_detail.html
。這時(shí)候默認(rèn)引入的render
方法開(kāi)始起作用了窗怒。我們要將HttpResponse("文章內(nèi)容是{} <br> 標(biāo)題是{}".format(article.title, article.content))
這一行代碼換成render
方法可以做如下變換:
from django.shortcuts import render
from .models import Article
# Create your views here
def article_detail(request, article_id):
article = Article.objects.get(id = article_id)
context = dict()
context["article"] = article
return render(request, "article_detail.html", context)
同時(shí),在templates
文件夾下的article_detail.html
可以這樣寫(xiě):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article Detail</title>
</head>
<body>
<h2>{{ article.title }}</h2>
<!---article.title就是原models.py中的article對(duì)象屬性蓄拣,用兩個(gè)圓括號(hào)括起來(lái)--->
<hr>
<p>{{ article.content }}</p>
</body>
</html>
可以看到上面的html代碼中的<h2>{{ article.title }}</h2>
一行扬虚。這一行是Django模板的應(yīng)用。更多關(guān)于模板的可以點(diǎn)這里球恤。下面一行還有模板辜昵。
但這樣寫(xiě)的views.py
還有一個(gè)問(wèn)題。就是當(dāng)文章不存在時(shí)咽斧,怎么返回404信息堪置?于是我們發(fā)現(xiàn)django.http
有一個(gè)Http404
方法可以使用,于是我們可以引入它张惹。
from django.http import Http404
經(jīng)過(guò)優(yōu)化后舀锨,代碼可以變成如下形式:
# views.py
from django.shortcuts import render
from django.http import Http404
from .models imprt Article
# Create your views here
def article_detail(request, article_id):
try:
article = Article.objects.get(id = article_id)
context = dict()
context["article"] = article
return render(request, "article_detail.html", context)
except Article.DoesNotExist:
raise Http404("文章不存在!")
但這樣寫(xiě)的話依然很復(fù)雜宛逗,有沒(méi)有一個(gè)方法坎匿,可以在正常時(shí)返回結(jié)果,錯(cuò)誤時(shí)返回404呢雷激?有的替蔬。get_object_or_404
可以達(dá)到這一點(diǎn)。
from django.shortcuts import get_object_or_404
同樣屎暇,render
方法可以被簡(jiǎn)化為:
from django.shortcuts import render_to_response
通過(guò)一通操作后承桥,我們的代碼可以簡(jiǎn)化為:
# views.py
from django.shortcuts import render_to_response, get_object_or_404
from .models imprt Article
# Create your views here
def article_detail(request, article_id):
article = get_object_or_404(Article, pk = article_id)
context = dict()
context["article"] = article
return render_to_response("article_detail.html", context)
如果我們還想定義一個(gè)文章列表的view
,那么可以這樣操作:
# views.py
from django.shortcuts import render_to_response, get_object_or_404
from .models imprt Article
# Create your views here
def article_detail(request, article_id):
article = get_object_or_404(Article, pk = article_id)
context = dict()
context["article"] = article
return render_to_response("article_detail.html", context)
def article_list(request):
articles = Article.objects.all() # 用對(duì)象.objects方法
context = dict()
context["articles"] = articles
return render_to_response("article_list.html", context)
同理根悼,我們還需要定義article_list.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article List</title>
</head>
<body>
{% for article in articles %}
<a href = {% url "article_id" article.pk %}>{{ article.title }}</a>
{% endfor %}
</body>
</html>
中間的這段代碼非常顯眼:
{% for article in articles %}
<a href = {% url "article_id" article.pk %}>{{ article.title }}</a>
{% endfor %}
-
{% %}
這是模板語(yǔ)法凶异。 -
{% for %}
:模板中使用for循環(huán)的標(biāo)志,常與{% endfor %}
搭配使用番挺。 -
{% url %}
:url標(biāo)簽唠帝。后面兩個(gè)參數(shù),article_id
是我們?cè)?code>urls.py中指定的別名玄柏。path("article/<int:article_id>", article_detail, name = "article_id"),
襟衰。這就是前面為什么urls.py
中為什么要指定name參數(shù)的原因了。article.pk
指的是article = get_object_or_404(Article, pk = article_id)
中的pk = article_id
而寫(xiě)的粪摘。這個(gè)標(biāo)簽意思是article.title
顯示標(biāo)題瀑晒,鏈接指向具體的文章绍坝。
于是乎,這樣一來(lái)我們就實(shí)現(xiàn)了前后端分離苔悦。
2. 分會(huì)場(chǎng)路由
我在article中另創(chuàng)建了一個(gè)urls.py
轩褐,意思是每個(gè)應(yīng)用都應(yīng)有每個(gè)應(yīng)用的路由。這樣一來(lái)就不用總是去總應(yīng)用中的urls.py
中改來(lái)改去了玖详。
這樣做的好處是每個(gè)應(yīng)用都可以創(chuàng)建自己的路由把介,不用改來(lái)改去了,節(jié)省代碼量蟋座。
先看一下總應(yīng)用中怎樣包括分應(yīng)用路由的說(shuō)明:
Including another URLconf
- Import the include() function: from django.urls import include, path
- Add a URL to urlpatterns: path('blog/', include('blog.urls'))
翻譯一下:
- 開(kāi)頭引入
include()
函數(shù)拗踢; - 在
urlpatterns
列表中可以寫(xiě)元素如右:path('blog/', include('blog.urls'))
于是乎,我們的總會(huì)場(chǎng)的urls.py
可以修改如下:
from django.contrib import admin
# from django.urls import path
from django.urls import include,path # 引入include函數(shù)
from .views import index
# from article.views import article_detail, article_list
urlpatterns = [
path('admin/', admin.site.urls),
path("", index),
# path("article/<int:article_id>", article_detail, name = "article_id"), #原代碼向臀,被我注釋掉了
# path("article/", article_list, name = "article_list"), # 原代碼巢墅,被我注釋掉了
path("article/", include("article.urls")), # 新代碼,可以看到我們用了include函數(shù)之后是什么樣的
]
那么券膀,分會(huì)場(chǎng)的urls.py
要怎么寫(xiě)呢君纫?
- 首先,仿照總會(huì)場(chǎng)芹彬,
from django.urls import path
和定義urlpatterns
列表是必須的蓄髓。 - 然后,引入本應(yīng)用的
views
雀监∷海可以寫(xiě)作from . import views
- 最后,改一下總會(huì)場(chǎng)被我注釋的兩行代碼即可寫(xiě)成会前。
最終效果如下:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from django.urls import path
from . import views
urlpatterns = [
path("<int:article_id>", views.article_detail, name="article_id"), # 相對(duì)路徑即可
path("", views.article_list, name="article_list"), # 已經(jīng)在總會(huì)場(chǎng)指定了分會(huì)場(chǎng)的上級(jí)路由是"articles/"了好乐,就不需要做重復(fù)工作了
]
這樣一來(lái),分會(huì)場(chǎng)的urls.py
便定義完成了瓦宜。