1. 程式人生 > >【Django】(4)建立其他頁面

【Django】(4)建立其他頁面

建立完了網站的主頁後,我們將建立兩個顯示資料的網頁,一個列出所有的主題,另一個顯示特定主題的所有條目。對於每個網頁,都要指定其URL模式,編寫一個檢視函式,一個模板。這樣做之前,可以先編寫一個父模板,讓專案中的其他模板都繼承它。

1.模板繼承

  1-1.父模板

  先建立一個base.html的模板,並將其儲存在index.html 所在的目錄中。base.html 包含所有頁面都有的元素,其他模板都繼承base.html。

base.html:

<p>
    <a href="{% url 'learning_logs:index' %}">
learning_logs</a> </p> {% block content %} {% endblock content %}

其中{%%}是模板標籤,href中的learning_logs:index生成一個URL,該URL與learning_logs/urls.py中定義的名為index的URL模式匹配。

其中learning_logs是一個名稱空間,而index是該名稱空間中的一個名稱獨特的URL模式匹配。

content為佔位符,其中的資訊由子模版來指定。子模版並非必須定義父模板中的每個塊,因此在父模板中可使用任意多個content來預留空間,而子模版可根據需要定義相應數量的塊。

  1-2.子模版

  現在需要重新編寫index.html,使其繼承base.html,如下所示:

index.html

{% extends "learning_logs/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 %}

  修改為如上,在塊中填入HTML程式碼。這種繼承的方式的好處是,當網頁多了起來,管理的時候方便了許多。

2.顯示所有主題的頁面

  2-1 URL模式

    定義一個用來顯示所有主題的主題的頁面URL。http://localhost:8000/topics將返回顯示所有主題的條目。

    先修改learning_logs/urls.py:

    urls.py

"""learing_logs應用程式中的URL模式"""
from django.conf.urls import url
from . import views

urlpatterns = [
    #主頁
    url(r'^$', views.index, name='index'),
    #顯示所有的主題
    url(r'^topics/$',views.topics,name='topics'),
]
app_name = 'learning_logs'  #自定義的應用程式的名字

  在這裡可以比較顯示主頁的程式碼,呼叫的檢視函式不一樣,前面呼叫views中的index,後者呼叫了views中的topics。

 2-2.檢視

    還未在views.py中新增topics,所以現在來新增views.py中的程式碼。

from django.shortcuts import render
from .models import Topic  #使用到資料庫時需要匯入
# Create your views here.
def index(request):
    #省略
def topics(request):
    topics = Topic.objects.order_by('data_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)

   一定從model中匯入Topic函式

  2-3.模板

    在index.html的同一目錄下,新建一個topics.html,新增如下程式碼:

{% extends "learning_logs/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 %}

其中的{% for item in list %} do somethong with each item {% endfor %} 在這個迴圈中,要將每個主題轉化為一個專案列表項。要在模板中打印出變數,需要將變數名用雙花括號括起來。每次迴圈時,程式碼

{{topic}}都將被替換為當前的topic的值

{% empty % } 告訴Django在列表為空時該如何處理。

  現在需要修改父模板,使其包含到顯示所有主題(topics.html)的頁面的連結

<p>
    <a href="{% url 'learning_logs:index' %}">learning_logs</a>
    <a href="{% url 'learning_logs:topics' %}">topics</a>
</p>
{% block content %}
{% endblock content %}

3.顯示特定主題的頁面

  現在需要建立一個專注於特定主題的頁面--顯示該主題的名稱以及該主題的所有條目。同樣,將定義一個新的URL模式,編寫一個檢視並建立一個模板。還將修改顯示所有主題的頁面,讓每個專案列表項都是一個連結,單擊將顯示相應的主題的所有條目。

  3-1.URL模式

  它將使用主題的id屬性來指出請求的時哪個主題。例如,檢視Chess(其id為1)的詳細頁面,URL 將為http://localhost:8000/topics/1/。現在修改learning_logs/urls.py:

"""learing_logs應用程式中的URL模式"""
from django.conf.urls import url
from . import views

urlpatterns = [
    #省略
    url(r'^topics/(?P<topics_id>\d+)/$',views.topic,name='topic'),
]
app_name = 'learning_logs'  #自定義的應用程式的名字

?P<topics_id>\d+中,\d+是匹配一個數字,將匹配到的數字存入topics_id中

  3-2.檢視

#省略
def topic(request,topic_id):
    """顯示單個主題及其所有條目"""
    topic = Topic.objects.get(id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic':topic,'entires':entries}
    return render(request, 'learning_logs/topic.html',context)

  3-3.模板

  在目錄中新增topic.html,新增如下程式碼:

{% extends 'learning_logs/base.html' %}

{% block content %}
<p>Topic:{{topic}}</p>
<p>Entries:</p>
<ul>
    { for entry in entries }
    <li>
        <p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
        <p>{{ entry.text|linebreaks}}</p>
    </li>
    {% empty %}
    <li>There are no entries for this topic yet.</li>
    {% endfor %}
</ul>
{% endblock content %}

    為了將每個條目變成連結,還需要修改topics.html中的for迴圈:

    {% for topic in topics %}
    <li><a href="{% url 'learning_logs:topic' topic.id %}">{{topic}}</a></li>
    {% empty %}
    <li>No topics have been added yet.</li>
    {% endfor %}

 如不成功,檢查程式碼。

親測效果如下: