1骡湖、建立項(xiàng)目
- 制定規(guī)范
編寫一個(gè)名為“學(xué)習(xí)筆記”的Web應(yīng)用程序榛臼,讓用戶能夠記錄感興趣的主題,并在學(xué)習(xí)每個(gè)主題的過程中添加條目恩静』篮粒“學(xué)習(xí)筆記”的主頁(yè)對(duì)這個(gè)網(wǎng)站進(jìn)行描述,并邀請(qǐng)用戶注冊(cè)或登錄驶乾。用戶登錄后邑飒,就可創(chuàng)建新主題、添加新條目以及閱讀既有的條目级乐。
- 建立虛擬環(huán)境
虛擬環(huán)境是系統(tǒng)思維一個(gè)位置疙咸,可以在其中安裝包,并將其與其他python包隔離风科。為項(xiàng)目新建一個(gè)目錄撒轮,將其命名為learning_note,再在終端中切換到這個(gè)目錄,并創(chuàng)建一個(gè)虛擬環(huán)境贼穆,我使用的是python 3.6.1题山。
learning_note> python -m venv ll_env
learning_note>
這里運(yùn)行模塊venv,并使用它來創(chuàng)建一個(gè)名為ll_env的虛擬環(huán)境故痊。
- 激活虛擬環(huán)境
learning_note>ll_env\Scripts\activate
(ll_env)learning_note>
環(huán)境處于活動(dòng)狀態(tài)時(shí)顶瞳,環(huán)境名將包含在括號(hào)內(nèi),在這種情況下愕秫,你可以在環(huán)境中安裝包浊仆,并使用已安裝的包。在ll_env中安裝的包僅在該環(huán)境處于活動(dòng)狀態(tài)時(shí)才可用豫领。
停止使用虛擬環(huán)境
(ll_env)learning_note>deactivate
learning_note>
-
安裝Django,它僅在虛擬環(huán)境處于活動(dòng)狀態(tài)時(shí)才可用
在Django中創(chuàng)建項(xiàng)目
(ll_env)learning_note>django-admin.py startproject learning_note .
(ll_env)learning_note>dir
learning_note ll_env manage.py
(ll_env)learning_note>dir learning_note
__init__.py settings.py urls.py wsgi.py
1.創(chuàng)建一個(gè)名為learning_note的項(xiàng)目抡柿,這個(gè)命令末尾的句點(diǎn)讓新項(xiàng)目使用合適的目錄結(jié)構(gòu),這樣開發(fā)完成后可輕松將應(yīng)用程序部署到服務(wù)器等恐。
2.文件settings.py指定Django如何與你的系統(tǒng)交互以及如何管理項(xiàng)目洲劣。
文件urls.py告訴Django應(yīng)創(chuàng)建哪些網(wǎng)頁(yè)來響應(yīng)瀏覽器請(qǐng)求。
文件wsgi.py幫助Django提供它創(chuàng)建的文件课蔬。
- 創(chuàng)建數(shù)據(jù)庫(kù)用于存儲(chǔ)項(xiàng)目中使用的信息
(ll_env)learning_note>python manage.py migrate
(ll_env)learning_note>dir
- 查看項(xiàng)目囱稽,核實(shí)Django是否正確地創(chuàng)建了項(xiàng)目
(ll_env)learning_note>python manage.py runserver
1、Django通過檢查確認(rèn)正確地創(chuàng)建了項(xiàng)目
2二跋、Django使用的版本以及當(dāng)前使用的設(shè)置文件的名稱
3战惊、指出項(xiàng)目的URL
現(xiàn)在打開一款Web瀏覽器,輸入你的URL:http://127.0.01:8000/扎即,如果這不管用吞获,請(qǐng)輸入http://localhost:8000/况凉。你將看到如下所示的頁(yè)面,這個(gè)頁(yè)面是Django創(chuàng)建的各拷,讓你知道到目前為止一切正车笕蓿。現(xiàn)在暫時(shí)不要關(guān)閉這個(gè)服務(wù)器烤黍。若要關(guān)閉這個(gè)服務(wù)器知市,按Ctrl+C即可。
注意:如果出現(xiàn)錯(cuò)誤消息:指定端口被占用速蕊,請(qǐng)執(zhí)行命令python manage.py runserver 8001嫂丙,讓Django使用另外一個(gè)端口;如果這個(gè)端口也不可用规哲,請(qǐng)不斷執(zhí)行上述命令奢入,直到找到可用的端口。
2媳叨、創(chuàng)建應(yīng)用程序
Django項(xiàng)目由一系列應(yīng)用程序組成腥光,它們協(xié)同工作,讓項(xiàng)目成為一個(gè)整體糊秆。我們暫時(shí)只創(chuàng)建一個(gè)應(yīng)用程序武福,它將完成項(xiàng)目的大部分工作。
當(dāng)前痘番,在前面打開的終端窗口中應(yīng)該還運(yùn)行著runserver捉片。請(qǐng)?jiān)俅蜷_一個(gè)終端窗口,并切換到manage.py所在的目錄汞舱。激活該虛擬環(huán)境:
learning_note>ll_env\Scripts\activate
(ll_env)learning_note>python manage.py startapp learning_notes
(ll_env)learning_note>dir
db.sqlite3 learning_note learning_notes ll_env manage.py
(ll_env)learning_note>dir learning_notes
admin.py __init__.py migrations models.py tests.py views.py apps.py
- 定義模型
每位用戶都需要在學(xué)習(xí)筆記中創(chuàng)建很多主題伍纫。用戶輸入的每個(gè)條目都與特定主題相關(guān)聯(lián),這些條目將以文本的方式顯示昂芜。我們還需要存儲(chǔ)每個(gè)條目的時(shí)間戳莹规,以便能夠告訴用戶各個(gè)條目都是什么時(shí)候創(chuàng)建的。
打開文件models.py(我這里使用的是pycharm 5.0.3版本的)
模型告訴Django如何處理應(yīng)用程序中存儲(chǔ)的數(shù)據(jù)泌神。在代碼層面良漱,模型就是一個(gè)類,包含屬性和方法欢际。下面表示用戶將要存儲(chǔ)的主題的模型:
class Topic(models.Model):
"""用戶學(xué)習(xí)的主題"""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""返回模型的字符串表示"""
return self.text
- 激活模型
要使用模型母市,必須讓Django將應(yīng)用程序包含到項(xiàng)目中。打開settings.py,你將看到一個(gè)片段损趋,它告訴Django哪些應(yīng)用程序安裝在項(xiàng)目中:
請(qǐng)將INSTALLED_APPS修改成下面這樣患久,將前面的應(yīng)用程序添加到這個(gè)元組中:
INSTALLED_APPS = (
'django.contrib.staticfiles'
# 我的應(yīng)用程序
'learning_notes',
)
讓Django修改數(shù)據(jù)庫(kù),使其能夠存儲(chǔ)與模型Topic相關(guān)的信息。
(ll_env)learning_note>python manage.py makemigrations learning_notes
命令makemigrations讓Django確定改如何修改數(shù)據(jù)庫(kù)蒋失,使其能夠存儲(chǔ)與我們定義的新模型相關(guān)聯(lián)的數(shù)據(jù)返帕。輸出表明Django創(chuàng)建了一個(gè)名為0001_initial.py的遷移文件,這個(gè)文件將在數(shù)據(jù)庫(kù)中為模型Topic創(chuàng)建一個(gè)表高镐。
應(yīng)用遷移溉旋,讓Django替我們修改數(shù)據(jù)庫(kù):
(ll_env)learning_note> python manage.py migrate
每當(dāng)修改“學(xué)習(xí)筆記”管理的數(shù)據(jù)時(shí)畸冲,都采用如下三個(gè)步驟:
- 修改models.py
- 對(duì)learning_notes調(diào)用makemigrations
- 讓Django遷移項(xiàng)目
- Django管理網(wǎng)站
為應(yīng)用程序定義模型時(shí)嫉髓,Django提供的管理網(wǎng)站讓你能夠輕松地處理模型。網(wǎng)站的管理員可使用管理網(wǎng)站邑闲,但普通用戶不能使用算行。建議管理網(wǎng)站,并通過它使用模型Topic來添加一些主題苫耸。
- 創(chuàng)建超級(jí)用戶
(ll_env)learning_note> python manage.py createsuperuser
- 向管理網(wǎng)站注冊(cè)模型
Django自動(dòng)在管理網(wǎng)站中添加了一些模型州邢,如User和Group,但對(duì)于我們創(chuàng)建的模型褪子,必須手工進(jìn)行注冊(cè)量淌。
我們創(chuàng)建應(yīng)用程序learning_notes時(shí),Django在models.py所在的目錄中創(chuàng)建了一個(gè)名為admin.py的文件:
為向管理網(wǎng)站注冊(cè)Topic,請(qǐng)輸入下面的代碼:
from learning_notes.models import Topic
admin.site.register(Topic)
這些代碼導(dǎo)入我們要注冊(cè)的模型Topic,再使用admin.site.register()讓Django通過管理網(wǎng)站管理我們的模型嫌褪。
現(xiàn)在呀枢,使用超級(jí)用戶賬戶訪問管理網(wǎng)站:訪問http://localhost:8000/admin/,并輸入你剛創(chuàng)建的超級(jí)用戶的用戶名和密碼笼痛,這個(gè)網(wǎng)頁(yè)讓你能夠添加和修改用戶和用戶組裙秋,還可以管理與剛才定義的模型Topic相關(guān)的數(shù)據(jù)。
3.添加主題
單擊Topics進(jìn)入主題網(wǎng)頁(yè)缨伊,它幾乎是空的摘刑,這是因?yàn)槲覀儧]有添加任何主題。單擊Add刻坊,你將看到一個(gè)用于添加新主題的表單枷恕。在第一個(gè)方框中輸入Sichuan Cuisine ,再單擊Save谭胚,將返回到主題管理頁(yè)面活尊。
- 定義模型Entry
要記錄學(xué)到的四川菜系和廣東菜系知識(shí),需要為用戶可在學(xué)習(xí)筆記中添加的條目定義模型漏益。每個(gè)條目都與特定主題相關(guān)聯(lián)蛹锰,這種關(guān)系被稱為多對(duì)一關(guān)系,即多個(gè)條目可關(guān)聯(lián)到同一個(gè)主題绰疤。
models.py
from django.db import models
# Create your models here.
class Topic(models.Model):
"""用戶學(xué)習(xí)的主題"""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
class Entry(models.Model):
"""學(xué)到的有關(guān)某個(gè)主題的具體知識(shí)"""
topic = models.ForeignKey(Topic) #將每個(gè)條目關(guān)聯(lián)到特定的主題
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
#存儲(chǔ)用于管理模型的額外信息铜犬,讓Django在需要的時(shí)使用Entries來管理多個(gè)條目
class Meta:
verbose_name_plural = 'entries'
#方法__str__()告訴Django,呈現(xiàn)條目時(shí)應(yīng)該顯示哪些信息
def __str__(self):
"""返回模型的字符串表示"""
return self.text[:50] + "..."
- 遷移模型Entry
因?yàn)槲覀兲砑恿艘粋€(gè)模型,因此需要再次遷移數(shù)據(jù)庫(kù)癣猾,修改models.py敛劝,執(zhí)行命令python manage.py makemigrations learning_notes,再執(zhí)行命令python manage.py migrate纷宇。
(ll_env)learning_note> python manage.py makemigrations learning_notes
(ll_env)learning_note>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, learning_notes, sessions
Running migrations:
Applying learning_notes.0002_entry... OK
- 向管理網(wǎng)站注冊(cè)Entry
admin.py
from learning_notes.models import Topic,Entry
admin.site.register(Topic)
admin.site.register(Entry)
返回到http://localhost:8000/admin/夸盟,你將看到learning_notes下列出了Entries。單擊Entries的Add鏈接像捶,選擇我們之前創(chuàng)建過的主題并添加相應(yīng)的條目上陕。
- Django shell
輸入一些數(shù)據(jù)后,就可以通過交互式終端會(huì)話以編程方式查看這些數(shù)據(jù)了拓春。這種交互式環(huán)境稱為Django shell释簿,是測(cè)試項(xiàng)目和排除其故障的理想之地。
(ll_env)learning_note> python manage.py shell
>>> from learning_notes.models import Topic
>>> Topic.objects.all()
<QuerySet [<Topic: Topic object>, <Topic: Topic object>]>
>>>
3硼莽、創(chuàng)建網(wǎng)頁(yè):學(xué)習(xí)筆記主頁(yè)
使用Django創(chuàng)建網(wǎng)頁(yè)的過程通常分為三個(gè)階段:定義URL庶溶、編寫視圖和編寫模板。
每個(gè)URL都被映射到特定的視圖——視圖函數(shù)獲取并處理網(wǎng)頁(yè)所需的數(shù)據(jù)懂鸵。視圖函數(shù)通常調(diào)用一個(gè)模板偏螺,后者生成瀏覽器能夠理解的網(wǎng)頁(yè)。
- 映射URL
用戶通過在瀏覽器中輸入U(xiǎn)RL以及單擊鏈接來請(qǐng)求網(wǎng)頁(yè)匆光,因此我們需要確定項(xiàng)目需要哪些URL套像。主頁(yè)的URL最重要,它是用戶用來訪問項(xiàng)目的基礎(chǔ)URL.當(dāng)前殴穴,基礎(chǔ)URL(http://localhost:8000/)返回默認(rèn)Django網(wǎng)站 凉夯,讓我們知道正確地建立了項(xiàng)目。
urls.py
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
該模塊定義了可在管理網(wǎng)站中請(qǐng)求的所有的URL采幌。
我們需要包含learning_notes的URL:
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'',include('learning_notes.urls',namespace='learning_notes')),
]
默認(rèn)的urls.py包含在文件夾learning_note中劲够,現(xiàn)在我們需要在文件夾learning_notes中創(chuàng)建另一個(gè)urls.py文件:
urls.py
"""定義learning_notes的URL模式"""
from django.conf.urls import url
from . import views
urlpatterns = [
#主頁(yè)
url(r'^$',views.index,name='index'),
]
- 此為基礎(chǔ)URL,url()的第二個(gè)實(shí)參指定了要調(diào)用的視圖函數(shù)休傍。請(qǐng)求的url與前述正則表達(dá)式匹配時(shí)征绎,Django將調(diào)用views.index,第三個(gè)實(shí)參將這個(gè)URL的名稱指定為index,讓我們能夠在代碼的其他地方引用它磨取。
- 編寫視圖
視圖函數(shù)接受請(qǐng)求中的信息人柿,準(zhǔn)備好生成網(wǎng)頁(yè)所需的數(shù)據(jù),再將這些數(shù)據(jù)發(fā)送給瀏覽器忙厌。
views.py
from django.shortcuts import render
# Create your views here.
函數(shù)render()根據(jù)視圖提供的數(shù)據(jù)渲染響應(yīng)凫岖,
from django.shortcuts import render
# Create your views here.
def index(request):
"""學(xué)習(xí)筆記的主頁(yè)"""
return render(request,'learning_notes/index.html')
- 編寫模板
模板定義了網(wǎng)頁(yè)的結(jié)構(gòu)。模板指定了網(wǎng)頁(yè)是什么樣子的逢净,而每當(dāng)網(wǎng)頁(yè)被請(qǐng)求時(shí)哥放,Django將填入相關(guān)的數(shù)據(jù)歼指。模板讓你能夠訪問視圖提供的任何數(shù)據(jù)。
在文件夾learning_notes中新建一個(gè)文件夾甥雕,并將其命名為templates踩身。在文件夾templates中,再新建一個(gè)文件夾社露,并將其命名為learning_notes挟阻。再最里面的文件夾learning_notes中,新建一個(gè)文件峭弟,并將其命名為
index.html:
<p>Learning Log</p>
<p>Learning Log helps you keep track of your learning, for any
topic you're learning about.</p>
此時(shí)請(qǐng)求默認(rèn)URL附鸽,將出現(xiàn)如下結(jié)果:
4、 創(chuàng)建其他網(wǎng)頁(yè)
- 模板繼承
1.父模板
base.html
<p>
<a href="{% url 'learning_notes:index' %}">Learnning Log</a>
</p>
{% block content %}{% endblock content %}
2.子模塊
index.html
{% extends "learning_notes/base.html" %}
{% block content %}
<p>Learning Log</p>
<p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p>
{% endblock content %}
- 顯示所有主題的頁(yè)面
1.URL模式
from django.conf.urls import url
from . import views
urlpatterns = [
#主頁(yè)
url(r'^$',views.index, name='index'),
#顯示所有的主題
url(r'^topics/$',views.topics,name='topics'),
]
2.視圖
views.py
from django.shortcuts import render
from .models import Topic
# Create your views here.
def index(request):
"""學(xué)習(xí)筆記的主頁(yè)"""
return render(request,'learning_notes/index.html')
def topics(request):
#顯示所有的主題
topics = Topic.objects.order_by('date_added')
context = {'topics':topics}
return render(request,'learning_notes/topics.html',context)
base.html
<p>
<a href="{% url 'learning_notes:index' %}">Learnning Log</a> -
<a href="{% url 'learning_notes:topics' %}">Topics</a>
</p>
{% block content %}{% endblock content %}
- 顯示特定主題的頁(yè)面
1.URL模式
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
#主頁(yè)
url(r'^$',views.index, name='index'),
#顯示所有的主題
url(r'^topics/$',views.topics,name='topics'),
#特定主題的詳細(xì)頁(yè)面
url(r'^topics/(?P<topic_id>\d+)/$',views.topics,name='topics'),
]
2.視圖
views.py
from django.shortcuts import render
from .models import Topic
# Create your views here.
def index(request):
"""學(xué)習(xí)筆記的主頁(yè)"""
return render(request,'learning_notes/index.html')
def topics(request):
#顯示所有的主題
topics = Topic.objects.order_by('date_added')
context = {'topics':topics}
return render(request,'learning_notes/topics.html',context)
def topic(request,topic_id):
#顯示單個(gè)主題及其所有的條目
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic':topic,'entries':entries}
return render(request,'learning_notes/topic.html',context)
3.模板
topic.html