發起討論主題
本專案內有兩種類型的資料:討論主題以及針對某主題的回覆。
定義討論主題資料表
修改 forum/topic/models.py
,內容如下:
from django.db import models
from django.contrib.auth.models import User
class Topic(models.Model):
subject = models.CharField('討論主題', max_length=255)
content = models.TextField('內文')
author = models.ForeignKey(User, on_delete=models.CASCADE)
created = models.DateTimeField('建立時間', auto_now_add=True)
replied = models.DateTimeField('回覆時間', null=True, blank=True)
def __str__(self):
return "{}: {}".format(self.author, self.subject)
```
執行以下指令將資料模型的變更套用到資料庫,並建立一個管理員的帳號:
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
開啟網站服務
python manage.py runserver 0.0.0.0:80
定義網站存取路徑規則
新增第 18, 22, 23 行:
from django.contrib import admin
from django.urls import path, include
from django.views.generic import RedirectView
urlpatterns = [
path('admin/', admin.site.urls),
path('topic/', include('topic.urls')),
path('', RedirectView.as_view(url='topic/')),
]
接著,為應用程式 topic
新增路徑規則。請新增檔案 forum/topic/urls.py
,內容如下:
from django.urls import path
from .views import *
urlpatterns = [
path('', TopicList.as_view(), name='topic_list'),
path('new/', TopicNew.as_view(), name='topic_new'),
path('<int:pk>/', TopicView.as_view(), name='topic_view'),
]
定義處理視圖
接著來撰寫每條路徑規則相對應的處理視圖,請開啟 forum/topic/views.py
,修改為以下程式碼:
from django.views.generic import *
from django.urls import reverse
from .models import *
class TopicList(ListView):
model = Topic
ordering = ['-created']
paginate_by = 20
class TopicNew(CreateView):
model = Topic
fields = ['subject', 'content']
def get_success_url(self):
return reverse('topic_list')
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
class TopicView(DetailView):
model = Topic
頁面範本
先前在建立專案時,已修改過專案設定檔 forum/forum/settings.py
,指定了要將頁面範本放在專案的 pagetmpl
資料夾中,記得在撰寫頁面範本之前,要先在專案資料夾中建立 pagetmpl
資料夾。
網站基底範本
新增網站基底範本檔案 forum/pagetmpl/base.html
,同樣引用了 Bootstrap
與 Font Awesome
兩個框架來調整網站的外觀:
<!doctype html>
<html lang="zh-hant">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" integrity="sha384-DNOHZ68U8hZfKXOrtjWvjxusGo9WQnrNx2sqG0tfsghAvtVlRW3tvkXWZh58N9jp" crossorigin="anonymous">
<title>討論區</title>
</head>
<body>
<div class="container">
{% include "navbar.html" %}
{% block content %}{% endblock %}
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>
</body>
</html>
導覽列
新增導覽列範本 forum/pagetmpl/navbar.html
:
<nav class="navbar navbar-expand-sm navbar-dark bg-primary mb-2">
<div class="navbar-brand">
<i class="far fa-comment-alt"></i> 討論區
</div>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a href="{% url 'topic_list' %}" class="nav-link">
<i class="fas fa-list"></i> 所有主題
</a>
</li>
<li class="nav-item">
<a href="{% url 'topic_new' %}" class="nav-link">
<i class="fas fa-edit"></i> 發起討論
</a>
</li>
</ul>
</div>
</nav>
討論主題列表
先新增資料夾 forum/pagetmpl/topic
,然後新增討論主題列表範本檔案 forum/pagetmpl/topic/topic_list.html
:
{% extends "base.html" %}
{% block content %}
<table class="table table-sm">
<thead>
<tr class="text-light bg-dark">
<th>發起時間</th>
<th>討論主題</th>
<th>發起人</th>
<th>回覆時間</th>
</tr>
</thead>
<tbody>
{% for topic in topic_list %}
<tr>
<td>{{topic.created|date:"Y/m/d H:i"}}</td>
<td>
<a href="{% url 'topic_view' topic.id %}">{{ topic.subject }}</a>
</td>
<td>{{topic.author}}</td>
<td>{{topic.replied|date:"Y/m/d H:i"}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% include "pagination.html" %}
{% endblock %}
分頁控制項同樣分開寫,如果需要的話,就可以直接引用。新增分會控制項的範本檔 forum/pagetmpl/pagination.html
:
{% if is_paginated %}
{% with btn_class="btn btn-sm btn-secondary" %}
<div>
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}" class="{{ btn_class }}">
<i class="fas fa-chevron-circle-left"></i>上一頁
</a>
{% endif %}
{% for page in paginator.page_range %}
{% if page == page_obj.number %}
<button class="{{ btn_class }}" disabled>{{ page }}</button>
{% else %}
<a href="?page={{ page }}" class="{{ btn_class }}">{{ page }}</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}" class="{{ btn_class }}">
下一頁<i class="fas fa-chevron-circle-right"></i>
</a>
{% endif %}
</div>
{% endwith %}
{% endif %}
檢視討論主題
新增討論主題檢視範本檔案 forum/pagetmpl/topic/topic_detail.html
:
{% extends "base.html" %}
{% block content %}
<div class="card">
<div class="card-header d-md-flex justify-content-between">
<div class="h3">{{ topic.subject }}</div>
<div class="text-muted">
<small><i class="fas fa-user"></i> {{ topic.author }}</small>
<small><i class="fas fa-clock"></i> {{ topic.created|date:"Y/m/d H:i" }}</small>
</div>
</div>
<div class="card-body">
{{ topic.content|linebreaks }}
</div>
</div>
{% endblock %}
新增討論主題
新增表單範本檔案 forum/pagetmpl/topic/topic_form.html
:
{% extends "base.html" %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
<table class="table table-sm">
{{ form.as_table }}
</table>
<input type="submit" class="btn btn-primary" value="送出">
</form>
<script>
var inputs = document.querySelectorAll('table input, table textarea, table select');
inputs.forEach(function(item) {
item.classList.add('form-control');
});
</script>
{% endblock %}
發起討論主題
本專案內有兩種類型的資料:討論主題以及針對某主題的回覆。
定義討論主題資料表
修改
forum/topic/models.py
,內容如下:執行以下指令將資料模型的變更套用到資料庫,並建立一個管理員的帳號:
開啟網站服務
定義網站存取路徑規則
新增第 18, 22, 23 行:
接著,為應用程式
topic
新增路徑規則。請新增檔案forum/topic/urls.py
,內容如下:定義處理視圖
接著來撰寫每條路徑規則相對應的處理視圖,請開啟
forum/topic/views.py
,修改為以下程式碼:頁面範本
先前在建立專案時,已修改過專案設定檔
forum/forum/settings.py
,指定了要將頁面範本放在專案的pagetmpl
資料夾中,記得在撰寫頁面範本之前,要先在專案資料夾中建立pagetmpl
資料夾。網站基底範本
新增網站基底範本檔案
forum/pagetmpl/base.html
,同樣引用了Bootstrap
與Font Awesome
兩個框架來調整網站的外觀:導覽列
新增導覽列範本
forum/pagetmpl/navbar.html
:討論主題列表
先新增資料夾
forum/pagetmpl/topic
,然後新增討論主題列表範本檔案forum/pagetmpl/topic/topic_list.html
:分頁控制項同樣分開寫,如果需要的話,就可以直接引用。新增分會控制項的範本檔
forum/pagetmpl/pagination.html
:檢視討論主題
新增討論主題檢視範本檔案
forum/pagetmpl/topic/topic_detail.html
:新增討論主題
新增表單範本檔案
forum/pagetmpl/topic/topic_form.html
: