項目3 Web應用程序(第18章:Diango入門)


---恢復內容開始---

  昨天敲得忘記保存了。。。然后自動恢復了一些,有點難受。。。就當鞏固一遍吧。

18.1 建立項目

18.1.1 制定規范

  編寫一個名為“學習筆記”的Web應用程序,讓用戶能夠記錄感興趣的主題,並在學習每個主題的過程中添加日志條目。“學習筆記”的主頁對這個網站進行描述,並邀請用戶注冊或登錄。用戶登錄后,就可以創建新主題、添加新條目以及閱讀既有的條目。

18.1.2 建立虛擬環境

  要使用Django,首先需要建立一個虛擬工作環境。虛擬工作環境是系統的一個位置,你可以再其中安裝包,並將其與其他Python包隔離。

  為項目新建一個目錄,將其命名為learning_log,再在終端中切換到這個目錄,並創建一個虛擬環境。

       

18.1.4 激活虛擬環境

  Windows系統,使用命令11_env\Scripts\activate(不包含source)

  要停止使用虛擬環境,可執行命令deactivate

18.1.5 安裝Django

18.1.6 在Django中創建項目

   在仍然處於活動的虛擬環境的情況下(11_env包含在括號內),執行命令新建一個項目:

       

  這個命令末尾的句點讓新項目使用合適的目錄結構,千萬不能忘了這個句點,否則部署應用程序時,將遭遇一些配置問題。

  目錄learning_log包含4個文件,其中最重要的是settings.py、urls.py和wsgi.py。文件settings.py指定Django如何與你的系統交互以及如何管理項目。在開發項目的過程中,我們將修改其中一些設置,並添加一些設置。文件urls.py告訴Django應創建哪些網頁來響應瀏覽器請求。文件wsgi.py幫助Django提供它創建的文件,這個文件名是web server gateway interface(Web服務器網關接口)

18.1.7 創建數據庫

  為給項目“學習筆記”創建數據庫,請在處於活躍虛擬環境中的情況下執行下面的命令:

python manage.py migrate

  我們將修改數據庫稱為遷移數據庫,首次執行命令migrate時,將讓Django確保數據庫與項目的當前狀態匹配。在使用SQLite的新項目中首次執行這個命令時,Django將新建一個數據庫。

18.1.8 查看項目

  下面核實Django是否正確地創建了項目。為此,可執行命令runserver:

python manage.py runserver

  Django通過檢查確認正確地創建了項目;指出了使用的Django版本以及當前使用的設置文件的名稱;它指出了項目的URL。

  Django啟動一個服務器,讓你能夠查看系統中的項目,了解它們的工作情況。

  現打開一款Web瀏覽器,並輸入URL:http://localhost:8000/;如果不管用,請輸入http://127.0.0.1:8000/

18.2 創建應用程序

  Django項目由一系列應用程序組成,它們協同工作,讓項目成為一個整體。我們暫時只創建一個應用程序,它將完成項目的大部分工作。

  當前,在前面打開的終端窗口中應該還運行着runserver。請再打開一個終端窗口(或標簽頁),並切換到manage.py所在的目錄。激活虛擬環境,再執行命令startapp:

python manage.py startapp learning_logs

  命令startapp appname讓Django建立創建應用程序所需的基礎設施。項目目錄增加一個文件夾learning_logs。打開這個文件夾,其中最重要的文件是models.py、admin.py和views.py。我們將使用models.py來定義我們要在應用程序中管理的數據。

18.2.1 定義模型

  打開文件models.py,下面表示用戶將要存儲的主題的模型:

from django.db import models

# 定義了一個名為Topic的類,它繼承了Model—Django中一個定義了模型基本功能的類
# 屬性text是一個CharField—由字符或文本組成的數據。需要存儲少量的文本,如名稱、標題或城市時,可以使用
#  date_added是一個DateTimeField—記錄日期和時間的數據。
class Topic(models.Model):
    """用戶學習主題"""
    text = models.CharField(max_length=200)
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        """返回模型的字符串表示"""
        return self.text

  注意,要或許可在模型中使用的各種字段,請參閱Django Model Field Reference(Django模型字段參考),其網址為https://docs.djangoproject.com/en/1.8/ref/models/fields/

18.2.2 激活模型

  要使用模型,必須讓Django將應用程序包含到項目中。為此,打開dettings.py,你將看到下面的片段,這是一個元組,告訴Django是由哪些元組組成的。添加learning_logs。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # My apps
    'learning_logs',
]

  接下來,需要讓Django修改數據庫,使其能夠存儲與模型Topic相關的信息。為此在終端窗口執行命令:

python manage.py makemigrations learning_logs

  輸出表明Django創建了一個名為0001_initial.py的遷移文件,這個文件將在數據庫中為模型Topic創建一個表。

  下面來應用這種遷移。讓Django替我們修改數據庫:

python manage.py migrate

  每當需要修改“學習筆記”管理的數據時,都采取如下三個步驟:修改models.py;對learning_logs調用makemigrations;讓Django遷移項目。

18.2.3 Django管理網站

  為應用程序定義模型,Django提供的管理網站讓你能夠輕松地處理模型。網站的管理員可使用管理網站,但普通用戶不能使用。

1、創建超級用戶

python manage.py createsuperuser

  昨天的數據丟失啦,只能重新創建一個管理員了,密碼需要數字和字母的結合,email地址可為空。

2、向管理網站注冊模型

  Django自動在管理網站中添加了一些模型,如User和Group,但對於我們創建的模型,必須手工注冊。

  打開admin.py文件,為向管理網站注冊Topic,請輸入以下代碼:

from django.contrib import admin

from learning_logs.models import Topic

admin.site.register(Topic)

  現在,使用超級用戶賬戶訪問管理網站:http://localhost:8000/admin,這個網頁讓你能夠添加和修改用戶和用戶組,還可以管理與剛才定義的模型Topic相關的數據。

3、添加主題

18.2.4 定義模型Entry

  要記錄學到的國際象棋和攀岩知識,需要為用戶可在學習筆記中添加的條目定義模型。每個條目都與特定主題相關聯,這種關系被稱為多對一關系,即多個條目可關聯到同一主題。

  下面是模型Entry的代碼:

class Entry(models.Model):
    """學到的有關某個主題的具體知識"""
    # ForeignKey外鍵,引用了數據庫中的另一條記錄;
    # 每個主題創建時,都給它分配了一個鍵(或ID)。
    # 嵌套Meta類,Meta存儲用於管理模型的額外信息。
    topic = models.ForeignKey(Topic,on_delete=models.CASCADE)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    class Meta:
        verbose_name_plural = 'entries'
    def __str__(self):
        return self.text[:50]+"..."

18.2.5 遷移模型Entry

  由於我們添加了一個新模型,因此需要再次遷移數據庫。你將慢慢地對這個過程了如指掌:修改models.py,執行命令python manage.py makemigrations app_name,再執行命令python manage.py migrate。

  下面來遷移數據庫並查看輸出:

18.2.6 向管理網站注冊Entry

from django.contrib import admin

from learning_logs.models import Topic,Entry

admin.site.register(Topic)
admin.site.register(Entry)

  返回到http://localhost:8000/admin/(注意需要重新開啟服務器)

  下面添加條目:

18.2.7 Django shell

  輸入一些數據,就可以通過交互終端會話以編程方式查看這些數據了。這種交互式環境稱為Django shell,是測試項目和排除其他故障的理想之地。  

      

  返回一個列表,稱為查詢集(queryset)

  下面演示了如何查看分配給每個主題對象的ID:

     

  知道對象的ID后,就可獲取該對象並查看其任何屬性。下面來看看主題Chess的屬性text和date_added的值:

     

  我們還可以查看與主題相關聯的條目。前面我們給模型Entry定義了屬性topic,這是一個ForeignKey,將條目與主題關聯起來。利用這種關聯,Django能夠獲取與特定主題相關聯的所有條目:

       

  為通過外鍵關系獲取數據,可使用相關模型的小寫名稱、下划線和單詞set。

  注意,每次修改模型后,你都需要重啟shell,這樣才能看到修改的效果。如果想要退出shell會話,Windows系統可以按ctrl+Z,再按回車鍵。

  p369 18-2簡短的條目,使得50字以內不顯示省略號。

    class Meta:
        verbose_name_plural = 'entries'
    def __str__(self):
        if (len(self.text))>50:
            return self.text[:50]+"..."
        else:
            return self.text

  

18.3 創建網頁:學習筆記主頁

   使用Django創建網頁的過程通常分三個階段:定義URL、編寫視圖和編寫模塊。首先,你必須定義URL模式。URL模式描述了URL是如何設計的,讓Django知道如何將瀏覽器請求於網站URL匹配,以確定返回哪個網頁。

  每個URL都被映射到特定的視圖——視圖函數獲取並處理網頁所需的數據。視圖通常調用一個模板,后者生成瀏覽器能夠理解的網頁。

18.3.1 映射URL

  當前,基礎URL(http://localhost:8000/)返回默認的Django網站,讓我們知道正確地建立了項目。我們將修改這一點,將這個基礎URL映射帶“學習筆記”主頁。

  打開項目主文件夾learning_log中的文件urls.py:

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

  前兩行導入為項目和管理網站URL的函數和模塊。這個文件的主題定義了變量urlpatterns。在這個針對整個項目的urls.py文件中,變量urlpatterns包含項目中的應用程序的URL。我們需要包含learning_logs的URL:

from django.conf.urls import url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'',include('learning_logs.urls',namespace='learning_logs')),
]

  添加了一行代碼,讓我們能夠將learning_logs的URL同項目中的其他URL區分開來,這在項目開始擴展時很有幫助。

  默認的urls.py包含在文件夾learning_log中,現在我們需要在文件夾learning_logs中創建另一個urls.py文件:

"""定義learning_logs的URL模式"""
from django.conf.urls import url
from .import views

urlpatterns = [
    # 主頁
    url(r'^$',views.index,name='index')
]

  實際的URL模式是一個對函數url()的調用,這個函數接受三個實參。第一個是一個正則表達式。r'^$',其中r讓Python將接下來的字符串視為原始字符串,而引號告訴Python正則表達式始於和終於何處。脫字符(^)讓Python查看字符串的開頭,而美元符號讓Python查看字符串的末尾。總體而言,這個正則表達式讓Python查找開頭和末尾之間沒有任何東西的URL。url的第二個實參指定了要調用的視圖函數。第三個實參將這個URL模式的名稱指定為index,讓我們能夠在代碼的其他地方引用它。

18.3.2 編寫視圖

  視圖函數接受請求中的信息,准備好生成網頁所需的數據,再將這些數據發送給瀏覽器。

  learning_logs中的文件views.py是你執行命令python manage.py startapp時自動生成的,當前其內容如下:

from django.shortcuts import render

# Create your views here.

  為主頁編寫視圖:

from django.shortcuts import render

# Create your views here.
def index(request):
    """學習筆記的主頁"""
    return render(request,'learning_logs/index.html')

  URL請求與我們剛才定義的模式匹配時,Django將在文件views.py中查找函數index,再將請求對象傳遞給這個視圖函數。render()提供了兩個實參:原始請求對象以及一個可用於創建網頁的模板。下面來編寫這個模板。

18.3.3 編寫模板

  在文件夾learning_logs中新建一個文件夾,並將其命名為templates。在文件夾templates中,再創建一個文件夾,並將其命名為learning_logs,在最里面的文件夾learning_logs中,新建一個文件,並將其命名為index.html,再在這個文件中編寫如下代碼:

<p>Learning Log</p>
<p>Learning Log helps you keep track of your learning,for any topic you're
learning about</p>

  現在,如果你請求這個項目的基礎URL——http://localhost:8000/,將看到剛才創建的網頁,而不是磨人的Django網頁。

18.4 創建其他網頁

  我們將創建兩個顯示數據的網頁,其中一個列出所有的主題,另一個顯示特定主題的所有條目。對於每個網頁我們都將指定URL模式,編寫一個視圖函數,並編寫一個模板。但這樣做之前,先創建一個父模板,項目中的其他模板都繼承它。

18.4.1 模板繼承

  1、父模板

  首先創建一個名為base.html的模板,並將其存儲在index.html所在目錄中。這個文件包含所有頁面都有的元素;其他模板都繼承base.html。

<p>
    <a href="{% url 'learning_logs:index' %}">Learning Log</a>
</p>

{% block content %}{% endblock content %}

  這個文件的第一部分創建一個包含項目名的段落,該段落也是一個到主頁的鏈接。為創建鏈接,我們使用了一個模板標簽,它是用大括號和百分號表示的。

  在簡單的HTML頁面中,鏈接是使用錨標簽定義的:

<a href='link_url>link text</a>

  插入了塊標簽,這個快名為content,是一個占位符,其中包含的信息將由子模板指定。

  2、子模板

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

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

{% block content %}
    <p>Learning Log helps you keep track of your learning,for any topic you're
    learning about</p>
{% endblock content %}

18.4.2 顯示所有主題的頁面

  1、URL模式

  首先,定義顯示所有主題的頁面的URL。修改learning_logs/urls.py:

"""定義learning_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'),
]

  我們只是在正則表達式中添加了topics/。Django檢查請求的URL時,這個模式與這樣的URL匹配:基礎URL后面跟着topics。可以在末尾包含斜杠,也可以省略它,但單詞topics后面不能有任何東西,否則就與該模式不匹配。其URL與該模式匹配的請求都將交給views.py中的函數topics()進行處理。

  2、視圖

  函數topics()需要從數據庫中獲取一些數據,並將其發送給模板。我們需要在views.py中添加的代碼如下:

from django.shortcuts import render
from .models import Topic
# Create your views here.
def index(request):
    """學習筆記的主頁"""
    return render(request,'learning_logs/index.html')
def topics(request):
    """顯示所有的主題"""
    topics = Topic.objects.order_by('date_added')
    context = {'topics':topics}
    return render(request,'learning_logs/topics.html',context)

  3、模板

  創建一個文件,將其命名為topics.html,並存儲到index.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 %}

  這個網頁的主體是一個項目列表,其中列出了用戶輸入的主題。在標准HTML中,項目列表被稱為無序列表,用標簽<ul></ul>表示。

  在模塊中,每個for循環都必須使用{% endfor %}標簽來顯示地指出其結束的位置。因此在模塊中,循環類似於下面這樣:

{% for item in list %}
       do something witn each item
{% endfor %}

  現在需要修改父模板,使其包含到顯示所有主題的頁面的鏈接:

<p>
    <a href="{% url 'learning_logs:index' %}">Learning Log</a> -
    <a href="{% url 'learning_logs:topics'%}">Topics</a>
</p>

{% block content %}{% endblock content %}

  我們在主頁的鏈接后面添加了一個連字符,然后添加了一個到顯示所有主題的頁面的鏈接。

  現在如果刷新瀏覽器的主頁,將看到鏈接Topics。單擊這個鏈接,將看到:

18.4.3 顯示特定主題的頁面

  接下來,我們需要創建一個專注於特定主題的頁面——顯示該主題的名稱及該主題的所有條目。

  1、URL模式

"""定義learning_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'),
    # 顯示特定主題的詳細頁面
    url(r'^topics/(?P<topic_id>\d+)/$',views.topic,name='topic'),
]

  2、視圖

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

  date_added前面的減號指定降序排序。

  3、模板

  

{% 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 %}

  顯示當前的主題,它存儲在模板變量{{topic}}中。為什么使用變量topic呢?因為它包含在字典context中。

  每個項目列表都將列出兩項信息:條目的時間戳和完整的文本。未列出時間戳,我們顯示屬性gate_added的值。在Django模板中,豎線表示模板過濾器——對模板變量的值進行修改的函數。過濾器linebreaks將包含換行符的長條目轉換為瀏覽器能夠理解的格式,一面顯示為一個不間斷的文本塊。

  4、將顯示所有主題的頁面中的每個主題都設置為連接。

  在瀏覽器中查看特定主題的頁面前,我們需要修改模板topics.html,讓每個主題都鏈接到相應的網頁:

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

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

 

 

 

 

 

---恢復內容結束---


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM