# Django 2.0 文章集 [6] 進階特性完善 blog app
###### tags: `Django`, `django2.0`, `python`
## § 電子郵件分享貼文
- [ ] (1) [管理員 email] 到 mysite/settings.py 設定 SMTP
- [ ] (2) [管理員 email] 到以下網址 (Google) 設定允許低安全性應用程式
設定完後方可用該 email 寄信
http://myaccount.google.com/lesssecureapps
- [ ] (3) 開啟 django shell,測試是否能正常送信
> from django.core.mail import send_mail
> send_mail('Subject here', 'Here is the message.',\
'from@example.com',
['to@example.com'],\
fail_silently=False)
Example:
send_mail("一封限時批", "直面詛咒,心亦雀躍。",\
"sender_account@gmail.com",\
["receiver_account@gmail.com"],\
fail_silently=False)
- [ ] (4) 編輯 views.py
#### 加上避免 CSRF 攻擊的 token: {{ csrf_token }}
詳參: https://owasp.org/www-community/attacks/csrf
## § 添加標籤功能
pip install django-taggit==0.22.2
### 編輯 mysite/mysite/settings.py
INSTALLED_APPS 添加以下項目:
INSTALLED_APPS = [
...
"taggit",
]
### 編輯 mysite/blog/models.py
```
class Post(models.Model):
...
tags = TaggableManager()
```
>python manage.py makemigrations blog
> python manage.py migrate
### 用 shell 測試看看
> from blog.models import Post
### 為某篇文章加上標籤並印出測試
> post = Post.objects.get(id=1)
> post.tags.add("tutorial", "django")
> post.tags.all()
執行結果:
<QuerySet [<Tag: django>, <Tag: tutorial>]>
### 移除標籤並印出測試
> post.tags.remove("tutorial")
> post.tags.all()
執行結果:
<QuerySet [<Tag: django>]>
## 將視圖加入標籤功能
編輯 views.py
```
from taggit.models import Tag
def post_list(request, tag_slug=None):
tag_ = None
if tag_slug is not None:
tag_ = get_object_or_404(Tag, slug=tag_slug)
object_list = object_list.filter(tags__in=[tag_])
return render(... ,
{ ...
"tag": tag_})
```
## 編輯 mysite/blog/urls.py
將下列(之前設定的) URL 路徑取消註解
並加上一行新路徑(用於標籤),如下:
```
urlpatterns = [
path("", views.post_list, name="post_list"),
...
path("tag/<slug:tag_slug>/", views.post_list,
name="post_list_by_tag"),
]
```
P.S. 由於剛剛編輯過了 post_list 視圖
多傳了一個 tag 參數給模板 (且相關 URL 路徑也設定完畢)
此處需要「編輯模板」來顯示 tag 的相關資訊
編輯 mysite/blog/templates/blog/post/list.html
## 調整分頁機制以使用 all_posts
` {% include "pagination.html" with page=all_posts %}`
## 在 {% for %} 中加入印出標籤的程式碼如下:
```
{% for post in all_posts %}
{% if tag %}
<h2>有關 '{{ tag.name }}' 的所有貼文:</h2>
{% endif %}
...
...
<p class="tags">
文章分類:
{% for tag in post.tags.all %}
<a href='{% url "blog:post_list_by_tag" tag.slug %}'>
{{ tag.name }}
</a>
{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
...
...
{% endfor %}
```
做完上述 models, views, urls, templates 的修改
啟動 server 後應可看到列表頁的各文章都帶有"文章分類"
(若後台有添加文章分類),且點擊某一標籤,會導引到
一個「皆含有該分類的文章」的頁面。