使用Django建立“學習筆記”①
規範:編寫一個名為“學習筆記”的Web應用程式,讓使用者能夠記錄感興趣的主題,並在學習每個主題的過程中新增日誌條目。“學習筆記”的主頁對這個網站進行描述,並邀請使用者註冊或登入。使用者登入後,就可建立新的主題、新增新條目以及閱讀既有條目。
1.1 安裝virtualenv
pip install virtualenv
1.2 搭建虛擬環境
F:\xiangmu>virtualenv env11
1.3 啟用虛擬環境
env11\Scripts\activate
1.4 安裝Django
pip install Django
1.5 建立專案
(env11) F:\xiangmu>django-admin startproject studylog .#不要忘記末尾的空格句點 該句點讓新專案使用合適的目錄結構
在這過程中遇到了不少麻煩,最終解決方法:設定預設py檔案啟動方式為python.exe;命令列輸入pip install django(並非之前在虛擬環境);去掉django-admin字尾.py
1.6 建立資料庫
python manage.py migrate
1.7 檢視核實django專案
(env11) F:\xiangmu>python manage.py runserver#執行 Performing system checks... System check identified no issues (0 silenced).#檢查確認建立正確專案 September 19, 2018 - 07:22:23 Django version 2.1.1, using settings 'studylog.settings' Starting development server at http://127.0.0.1:8000/#指出了專案的url Quit the server with CTRL-BREAK.
2.1 定義模型
(env11) F:\xiangmu>python manage.py startapp studylogs #不同於studylog,新檔案,用於建立app所需的基本設施 (env11) F:\xiangmu>dir 驅動器 F 中的卷是 新加捲 卷的序列號是 66ED-CACB F:\xiangmu 的目錄 2018/09/19 週三 07:36 <DIR> . 2018/09/19 週三 07:36 <DIR> .. 2018/09/19 週三 07:15 131,072 db.sqlite3 2018/09/19 週三 05:28 <DIR> env11 2018/09/19 週三 07:06 555 manage.py #定義管理的資料 2018/09/19 週三 07:15 <DIR> studylog 2018/09/19 週三 07:36 <DIR> studylogs
# coding=utf-8
from django.db import models
#在這裡建立模型,模型即是一個類
class Topic(models.Model):
'''使用者學習的主題'''
text = models.CharField(max_length=200)#儲存少量文字,200個字元的預留空間
date_added = models.DateTimeField(auto_now_add=True)#記錄日期和時間的資料,並自動設定成當前日期和時間
def __str__(self):
'''返回模型的字串表示'''
return self.text
2.2 啟用模型
開啟位於studylog中的settings.py檔案,修改其部分,將之前的應用程式tian新增其中
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'studylogs'#剛才修改的models.py所在的資料夾
]
需要讓django修改資料庫,使其能夠儲存與模型相關的資訊
(env11) F:\xiangmu>python manage.py makemigrations studylogs#
Migrations for 'studylogs':
studylogs\migrations\0001_initial.py
- Create model Topic
(env11) F:\xiangmu>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, studylogs
Running migrations:
Applying studylogs.0001_initial... OK
(env11) F:\xiangmu>
每次需要修改管理的資料時,都有三個步驟:1.修改models.py 2.對studylogs呼叫makemigrations 3.讓Django遷移專案
2.3 Django管理網站
①建立超級使用者(管理員)
(env11) F:\xiangmu>python manage.py createsuperuser
Username (leave blank to use 'administrator'): admin
Email address: [email protected]
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is entirely numeric.
Bypass password validation and create user anyway? [y/N]: N
Password:
Password (again):
Superuser created successfully.
②向管理網站註冊模型
開啟studylogs下的admin.py,修改其資料
from django.contrib import admin
# Register your models here.
from studylogs.models import Topic#匯入要註冊的Topic類
admin.site.register(Topic)#讓Django通過管理網站管理模型
③新增主題
2.4 定義模型Entry
需要為使用者可在學習筆記中新增的條目定義模型,每個條目都與特定主題相關聯,即多對一的關係。
class Entry(models.Model):
'''學到的有關某個主題的特定知識'''
topic = models.ForeignKey(Topic,on_delete=models.CASCADE)#foreignkey外來鍵,引用資料庫的另一條記錄
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)#按建立順序顯示條目,並顯示時間戳
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
return self.text[:50] + '...'
2.5 遷移模型Entry
(env11) F:\xiangmu>python manage.py makemigrations studylogs
Migrations for 'studylogs':
studylogs\migrations\0002_entry.py
- Create model Entry
(env11) F:\xiangmu>python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions, studylogs
Running migrations:
Applying studylogs.0002_entry... OK
2.6 向管理網站註冊Entry
from django.contrib import admin
# Register your models here.
from studylogs.models import Topic,Entry
admin.site.register(Topic)
admin.site.register(Entry)
修改admin.py檔案
2.7 django shell
django shell:通過互動式終端會話以程式設計方式檢視資料,是測試專案和排除故障的理想之地。例如
(env11) F:\xiangmu>python manage.py shell
Python 3.6.5 |Anaconda, Inc.| (default, Mar 29 2018, 13:32:41) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from studylogs.models import Topic#這裡匯入模組studylogs中的模型topic
>>> Topic.objects.all()#返回一個列表,查詢集
<QuerySet [<Topic: Chess>, <Topic: Game>]>
#可以進行遍歷,查詢id,通過id檢視其屬性
>>> topics = Topic.objects.all()
>>> for topic in topics:
... print(topic.id,topic)
...
1 Chess
2 Game
>>> t = Topic.objetcs.get(id=2)
Traceback (most recent call last):
File "<console>", line 1, in <module>
AttributeError: type object 'Topic' has no attribute 'objetcs'
>>> t = Topic.objects.get(id=2)
File "<console>", line 1
t = Topic.objects.get(id=2)
^
IndentationError: unexpected indent
>>> t = Topic.objects.get(id=2)
>>> t.text
'Game'
>>> t.date_added
datetime.datetime(2018, 9, 19, 0, 33, 9, 870659, tzinfo=<UTC>)
ctrl+z退出shell
3.1 對映URL
開啟studylog中的url.py:
from django.contrib import admin
from django.urls import path
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('studylogs.urls',namespace='studylogs')),
]
需要在studylogs中建立另一個urls.py檔案:(難)
# coding=utf-8
'''定義studylogs的url模式'''
from django.urls import path
from . import views
app_name='studylogs'
urlpatterns = [
path('',views.index,name='index'),
]#URL模式三個實參 正則表示式 呼叫的檢視函式將其命名為index
最後網站無法開啟排查原因,出現在了這裡,django2與django1在url上語法不同,1→2:urls→path,取消了之前的正則表示式url模式
3.2 編寫檢視
開啟views.py
from django.shortcuts import render
# Create your views here.
def index(request)#主頁
return render(request,'studylogs/index.html')
3.3 編寫模板
在studylogs下新建一個templates(模板)資料夾,再在其中建立studylogs資料夾,在最新的studylogs資料夾中新建一個index.html的檔案,並且修改:
<p>study log</p>
<p>i will remember the day i did this</p>
4.1 模板繼承
建立父模板base.html
<p>
<a href="{% url 'studylogs:index' %}">studylog</a>
</p>
{% block content %}{% endblock content %}
修改子模板index.html
{% extends "studylogs/base.html"%}
{% block content %}
<p>i will remember the day i did this</p>
{% endblock content %}
4.2 url模式
修改studylogs下的urls.py
from django.urls import path
from . import views
app_name = 'studylogs'
urlpatterns = [
path('', views.index, name='index'),
path('topics/', views.topics, name='topics'),
]
修改views.py
from django.shortcuts import render
from .models import Topic
# Create your views here.
def index(request):
return render(request,'studylogs/index.html')
def topics(request):
topics = Topic.objects.order_by('date_added')#查詢資料庫,並按屬性date排序,儲存在topics中
context = {'topics':topics}#定義一個字典,將要傳送給字典的上下文
return render(request,'studylogs/topics.html',context)
建立一個顯示所有主題的模板,接受字典context
{% extends "studylogs/base.html"%}
{% block content %}
<p>Topics</p>
<ul>
{% for topic in topics %}
<li>{{ topic }}</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
{% endblock content %}
修改父模板,使其包含到顯示所有主題的頁面的連結
<p>
<a href="{% url 'studylogs:index' %}">studylog</a> -
<a href="{% url 'studylogs:topics' %}">Topics</a>
</p>
{% block content %}{% endblock content %}
4.3 顯示特定主題的頁面
urls.py
# coding=utf-8
'''定義studylogs的url模式'''
from django.urls import path,re_path
from . import views
app_name = 'studylogs'
urlpatterns = [
path('', views.index, name='index'),
re_path(r'^topics(?P<topic_id>\d+)/$', views.topics, name='topics'),
]
views.py
from django.shortcuts import render
from .models import Topic
# Create your views here.
def index(request):
return render(request,'studylogs/index.html')
def topics(request):
topics = Topic.objects.order_by('date_added')#查詢資料庫,並按屬性date排序,儲存在topics中
context = {'topics':topics}#定義一個字典,將要傳送給字典的上下文
return render(request,'studylogs/topics.html',context)
def topic(request,topic_id):
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('date_added')
context = {'topic':topic,'entries':entries}
return render(request,'studylogs/topic.html',context)