Django基本使用以及博客搭建的準備工作逝嚎,請參考Django入門與實踐
博客主頁面編寫
編寫思路
- 取出數(shù)據(jù)庫中所有文章對象
- 將文章對象打包成列表發(fā)送到前端
- 前端頁面以超鏈接的形式逐個列出
流程
- 后端
view.py
中傳遞對象列表
def index(request):
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles':articles})
- 前端
通過模板for循環(huán)顯示
{% for xx in xxs %}
html語句
{%endfor%}
注意這里不是{{ }}
而是{% %}
index.html
中
<html>
<head>
<title>my first html!</title>
</head>
<body>---
<h1>
<a href="">新文章</a>
</h1>
{%for article in articles %}
<a href="">{{article.title}}</a>
<br>
{% endfor %}
</body>---
</html>
瀏覽器打開地址http://localhost:8000/blog/index/
即可。
博客主頁面點擊鏈接進入文章
當點擊主頁面的文章標題后炉菲,跳轉(zhuǎn)到該文章頁面
流程
- 參數(shù)寫在響應函數(shù)
request
后堕战,可以有默認值
views.py
中
def article_page(request, article_id):
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/article.html', {'article':article})
- url正則表達式匹配
url.py
中
urlpatterns = [
url(r'^article/(?P<article_id>[0-9]+)$', views.article_page),
]
注意這里的組名:article_id>
必須和article_page()
中的形參article_id
一致
- 寫對應的
article.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article Page</title>
</head>
<body>
<h1>{{article.title}}</h1>
<br/>
<h3>{{article.content}}</h3>
<br/><br/>
<a herf="">修改文章</a>
</body>
</html>
瀏覽器輸入http://localhost:8000/blog/article/1
可以打開索引為1的文章頁面。
但是index
主頁面的超鏈接點擊沒有反應,需要額外的配置拍霜。
url鏈接配置
-
根url
嘱丢,寫在include()
的第二個參數(shù)位置,namespace = 'xxx'
myblog.urls.py
中
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^blog/', include('blog.urls', namespace='blog')),
]
- app的
urls.py
中url()
第3個位置祠饺,name =xxx
blog.urls.py
中
urlpatterns = [
url(r'^index/$', views.index),
url(r'^article/(?P<article_id>[0-9]+)$', views.article_page, name='article_page'),
]
- html修改
index.html
中的href
配置
<html>
<head>
<title>my first html!</title>
</head>
<body>---
<h1>
<a href="">新文章</a>
下</h1>
{%for article in articles %}
<a href="{% url 'blog:article_page' article.id %}">{{article.title}}</a>
<br>
{% endfor %}
</body>---
</html>
博客新建文章撰寫頁面
頁面內(nèi)容
- 標題編輯欄
- 文章內(nèi)容編輯區(qū)域
- 提交按鈕
- 后端獲取前端數(shù)據(jù)
- 存入數(shù)據(jù)庫
流程
- 編寫頁面
(1) view.py
def edit_page(request):
return render(request, 'blog/edit_page.html')
(2) 新建edit_page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Page</title>
</head>
<body>
<form action="" method="post">
<label>
文章標題
<input type="text" name="title"/>
</label>
<br/>
<label>
文章內(nèi)容
<input type="text" name="content"/>
</label>
<br/>
<br/>
<input type="submit" />
</form>
</body>
</html>
注意這里<input type="text" name="content"/>
的name
和后面post
獲取該前端數(shù)據(jù)的key值
必須相同越驻。
(3) urls.py
urlpatterns = [
url(r'^edit/$', views.edit_page),
]
瀏覽器輸入http://localhost:8000/blog/edit/
即可。
- 點擊
提交按鈕
后道偷,將前端頁面內(nèi)容返回給后端
(1) 使用request.POST['參數(shù)名']
來獲取前端的表單數(shù)據(jù)
blog.views.py
中編寫提交按鈕
的響應函數(shù)
def submit_action(request):
title = request.POST.get('title', 'TITLE')
content = request.POST.get('content', 'CONTENT')
models.Article.objects.create(title=title, content=content)
# 新文章提交后缀旁,默認返回主頁面
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles':articles})
注意這里post
獲取該前端數(shù)據(jù)的key值title
和content
必須和html中的輸入框的name
相同,比如<input type="text" name="content"/>
。
(2) 存入數(shù)據(jù)庫
models.Article.objects.create(title,content)
創(chuàng)建對象
(3) 配置url
blog.urls.py
urlpatterns = [
url(r'^submit_action/$', views.submit_action, name='submit_action'),
]
(4)提交按鈕
綁定url
edit_page.html
中為表單添加url
<form action="{% url 'blog:submit_action'%}" method="post">
</form>
(5) 瀏覽器中點擊提交按鈕
訪問頁面會發(fā)現(xiàn)報錯:
禁止訪問 (403)
CSRF驗證失敗. 請求被中斷.
Django中通過POST提交表單的時候需要添加
{% csrf_token %}
即:
<form action="{% url 'blog:submit_action'%}" method="post">
{% csrf_token %}
博客已提交的文章重新編輯界面
重新編輯文章頁面有文章內(nèi)容勺鸦,而新建文章編輯頁面沒有文章內(nèi)容并巍。
重新編輯的文章有文章對象,對象id是數(shù)據(jù)庫存入自動生成的鍵值换途,從1開始的整形數(shù)據(jù)懊渡。
而新建文章的頁面,id可以傳入默認值0進行區(qū)分军拟。
- 修改html
index.html
中
- 點擊新建文章返回
0
, 進入編輯頁面剃执。 - 點擊已有文章,返回文章
id
吻谋,進入文章頁面忠蝗。
<h1>
<a href="{% url 'blog:edit_page' 0 %}">新文章</a>
</h1>
{%for article in articles %}
<a href="{% url 'blog:article_page' article.id %}">{{article.title}}</a>
<br>
{% endfor %}
article.html
中
- 文章頁面的
編輯文章
按鈕,返回當前文章id漓拾,進入編輯頁面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Article Page</title>
</head>
<body>
<h1>{{article.title}}</h1>
<br/>
<h3>{{article.content}}</h3>
<br/><br/>
<a href="{% url 'blog:edit_page' article.id %}">編輯文章</a>
</body>
</html>
edit_page.html
中
- 如果編輯已有的文章阁最,后端會傳入
article
對象戒祠,更新前端的數(shù)據(jù)。 - 通過新增
hidden
的article_id
來標識提交的是新文章還是已有文章速种。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Edit Page</title>
</head>
<body>
<form action="{% url 'blog:submit_action'%}" method="post">
{% csrf_token %}
{% if article %}
<input type="hidden" name="article_id" value="{{article.id}}" >
<label>
文章標題
<input type="text" name="title" value={{article.title}} />
</label>
<br/>
<label>
文章內(nèi)容
<input type="text" name="content" value={{article.content}} />
</label>
<br/>
<br/>
{% else %}
<input type="hidden" name="article_id" value="0" >
<label>
文章標題
<input type="text" name="title"/>
</label>
<br/>
<label>
文章內(nèi)容
<input type="text" name="content"/>
</label>
<br/>
<br/>
{% endif %}
<input type="submit", name="提交" />
</form>
</body>
</html>
- 修改
view.py
(1) edit_page
函數(shù)
- 編輯已有文章姜盈,傳入
article
對象。 - 編輯新建文章配阵,不傳
article
對象馏颂。
def edit_page(request, article_id):
# 編輯文章的頁面
if str(article_id) == '0':
# 如果是新建文章,則直接編輯空文章
return render(request, 'blog/edit_page.html')
else:
# 如果編輯之前的文章棋傍,則傳入對象救拉,進行顯示
article = models.Article.objects.get(pk=article_id)
return render(request, 'blog/edit_page.html', {'article':article})
(2) submit_action
函數(shù)
-
article.html
進入的編輯頁面,傳入的article_id
不為0瘫拣,則更新數(shù)據(jù)庫的數(shù)據(jù) -
index.html
主頁面進入的新建文章的編輯頁面亿絮,傳入的article_id
為0,創(chuàng)建新的數(shù)據(jù)庫對象麸拄。
def submit_action(request):
# 編輯文章頁面的提交按鈕的處理行為
title = request.POST.get('title', 'TITLE')
content = request.POST.get('content', 'CONTENT')
article_id = request.POST.get('article_id', '0')
if article_id == '0':
models.Article.objects.create(title=title, content=content)
# 新文章提交后派昧,默認返回主頁面
articles = models.Article.objects.all()
return render(request, 'blog/index.html', {'articles':articles})
else:
article = models.Article.objects.get(pk=article_id)
article.title = title
article.content = content
article.save()
# 之前文章編輯后,返回文章頁面
return render(request, 'blog/article.html', {'article': article})
(3)修改urls.py
views.edit_page
的url
需要修改正則表達式
urlpatterns = [
url(r'^index/$', views.index),
url(r'^article/(?P<article_id>[0-9]+)$', views.article_page, name='article_page'),
url(r'^edit/(?P<article_id>[0-9]+)$', views.edit_page, name='edit_page'),
url(r'^submit_action/$', views.submit_action, name='submit_action'),
]
最后可以瀏覽器輸入地址http://localhost:8000/blog/index/
進行測試了拢切。
Templates 過濾器
這里用過濾器將代碼進行優(yōu)化
過濾器使用方法:
{{value|filter}}
過濾器可疊加
{{value|filter1|filter2}}
比如
{{list_nums|length}}
edit_page.html
中可以使用過濾器來簡化if else
<form action="{% url 'blog:submit_action'%}" method="post">
{% csrf_token %}
{% if article %}
<input type="hidden" name="article_id" value="{{article.id}}" >
<label>
文章標題
<input type="text" name="title" value={{article.title}} />
</label>
<br/>
<label>
文章內(nèi)容
<input type="text" name="content" value={{article.content}} />
</label>
<br/>
<br/>
{% else %}
<input type="hidden" name="article_id" value="0" >
<label>
文章標題
<input type="text" name="title"/>
</label>
<br/>
<label>
文章內(nèi)容
<input type="text" name="content"/>
</label>
<br/>
<br/>
{% endif %}
<input type="submit", name="提交" />
</form>
改為
<form action="{% url 'blog:submit_action'%}" method="post">
{% csrf_token %}
<input type="hidden" name="article_id" value="{{article.id|default:'0'}}" >
<label>
文章標題
<input type="text" name="title" value="{{article.title}} "/>
</label>
<br/>
<label>
文章內(nèi)容
<input type="text" name="content" value="{{article.content}}" />
</label>
<br/>
<br/>
<input type="submit", name="提交" />
</form>