2020年9月26日星期六

020 Python编程 從入門到實踐, 第二部分  專案3 Web應用程式 第 20 章 設置應用程式的樣式並對其進行部署

 申明本站飛宇網 https://feiyetopro.blogspot.com/自網路收集整理之書籍文章影音僅供預覽交流學習研究,其[書籍、文章、影音]情節內容, 評論屬其個人行為, 與本網站無關。版權歸原作者和出版社所有,請在下載 24 小時內刪除,不得用作商業用途;如果您喜歡其作品,請支持訂閱購買[正版]謝謝!



20 章 設置應用程式的樣式並對其進行部署

當前,專案學習筆記功能已齊備,但未設置樣式,也只是在本地電腦上運行。在本章中,我們將以簡單而專業的方式設置這個專案的樣式,再將其部署到一台伺服器上,讓世界上的任何人都能夠建立帳戶。

為設置樣式,我們將使用Bootstrap庫,這是一組工具,用於為Web應用程式設置樣式,使其在任何現代設備上都看起來很專業,無論是大型的平板顯示器還是智慧手機。為此,我們將使用應用程式django-bootstrap3,這也讓你能夠練習使用其他Django開發人員開發的應用程式。

我們將把專案學習筆記部署到Heroku,這個網站讓你能夠將項目推送到其伺服器,讓任何有網路連接的人都可使用它。我們還將使用版本控制系統Git來跟蹤對這個項目所做的修改。

完成專案學習筆記後,你將能夠開發簡單的Web應用程式,讓它們看起來很漂亮,再將它們部署到伺服器。你還能夠利用更高級的學習資源來提高技能。

20.1 設置專案學習筆記的樣式

我們一直專注於專案學習筆記的功能,而沒有考慮樣式設置的問題,這是有意為之的。這是一種不錯的開發方法,因為能正確運行的應用程式才是有用的。當然,應用程式能夠正確運行後,外觀就顯得很重要了,因為漂亮的應用程式才能吸引使用者使用它。

在本節中,我將簡要地介紹應用程式django-bootstrap3,並演示如何將其繼承到專案中,為部署專案做好準備。

20.1.1 應用程式django-bootstrap3

我們將使用django-bootstrap3來將Bootstrap繼承到項目中。這個應用程式下載必要的Bootstrap檔,將它們放到專案的合適位置,讓你能夠在專案的範本中使用樣式設置指令。

為安裝django-bootstrap3,在活動的虛擬環境中執行如下命令:

 

(ll_env)learning_log$ pip install django-bootstrap3

--snip--

Successfully installed django-bootstrap3

 

 

 

 

 

 

 

 

接下來,需要在settings.pyINSTALLED_APPS 中添加如下代碼,在專案中包含應用程式django-boostrap3

settings.py

 

--snip--

INSTALLED_APPS = (

    --snip--

    'django.contrib.staticfiles',

 

    # 協力廠商應用程式

    'bootstrap3',

 

    # 我的應用程式

    'learning_logs',

    'users',

)

--snip--

 

 

 

 

 

 

 

 

新建一個用於指定其他開發人員開發的應用程式的片段,將其命名為協力廠商應用程式,並在其中添加'bootstrap3' 。大多數應用程式都需要包含在INSTALLED_APPS 中,為確定這一點,請閱讀要使用的應用程式的設置說明。

我們需要讓django-bootstrap3包含jQuery,這是一個JavaScript庫,讓你能夠使用Bootstrap範本提供的一些互動式元素。請在settings.py的末尾添加如下代碼:

settings.py

 

--snip--

# 我的設置

LOGIN_URL = '/users/login/'

 

# django-bootstrap3的設置

BOOTSTRAP3 = {

    'include_jquery': True,

    }

 

 

 

 

 

 

 

 

這些代碼讓你無需手工下載jQuery並將其放到正確的地方。

20.1.2 使用Bootstrap來設置專案學習筆記的樣式

Bootstrap基本上就是一個大型的樣式設置工具集,它還提供了大量的範本,你可將它們應用於專案以創建獨特的總體風格。對Bootstrap初學者來說,這些範本比各個樣式設置工具使用起來要容易得多。要查看Bootstrap提供的範本,可訪問http://getbootstrap.com/ ,按一下Getting Started,再向下滾動到Examples部分,並找到Navbars in action。我們將使用範本Static top navbar,它提供了簡單的頂部導航條、頁面標題和用於放置頁面內容的容器。

20-1顯示了對base.html應用這個Bootstrap範本並對index.html做細微修改後的主頁。


20-1 專案學習筆記的主頁——使用Bootstrap設置樣式後

知道要獲得的效果後,接下來的內容理解起來將更容易。

20.1.3 修改base.html

我們需要修改範本base.html,以使用前述Bootstrap範本。我們把新的base.html分成幾個部分進行介紹。

1. 定義HTML頭部

base.html所做的第一項修改是,在這個檔中定義HTML頭部,使得顯示學習筆記的每個頁面時,流覽器標題列都顯示這個網站的名稱。我們還將添加一些在範本中使用Bootstrap所需的資訊。刪除base.html的全部代碼,並輸入下面的代碼:

base.html

 

{% load bootstrap3 %}

 

<!DOCTYPE html>

<html lang="en">

   <head>

      <meta charset="utf-8">

      <meta http-equiv="X-UA-Compatible" content="IE=edge">

      <meta name="viewport" content="width=device-width, initial-scale=1">

 

     <title>Learning Log</title>

 

     {% bootstrap_css %}

      {% bootstrap_javascript %}

 

   </head>

 

 

 

 

 

 

 

 

處,我們載入了django-bootstrap3中的範本標籤集。接下來,我們將這個檔聲明為使用英語(見編寫的HTML文檔(見)。HTML檔分為兩個主要部分:頭部 head)和主體 body);在這個檔中,頭部始於處。HTML檔的頭部不包含任何內容:它只是將正確顯示頁面所需的資訊告訴流覽器。在處,我們包含了一個title 元素,在流覽器中打開網站學習筆記的頁面時,流覽器的標題列將顯示該元素的內容。

處,我們使用了django-bootstrap3的一個自訂範本標籤,它讓Django包含所有的Bootstrap樣式檔。接下來的標籤啟用你可能在頁面中使用的所有互動式行為,如可折疊的巡覽列。處為結束標籤</head> 

2. 定義巡覽列

下面來定義頁面頂部的巡覽列:

 

  --snip--

    </head>

 

    <body>

 

      <!-- Static navbar -->

     <nav class="navbar navbar-default navbar-static-top">

        <div class="container">

 

          <div class="navbar-header">

           <button type="button" class="navbar-toggle collapsed"

                data-toggle="collapse" data-target="#navbar"

                aria-expanded="false" aria-controls="navbar">

            </button>

           <a class="navbar-brand" href="{% url 'learning_logs:index' %}">

                Learning Log</a>

          </div>

 

         <div id="navbar" class="navbar-collapse collapse">

           <ul class="nav navbar-nav">

             <li><a href="{% url 'learning_logs:topics' %}">Topics</a></li>

            </ul>

 

           <ul class="nav navbar-nav navbar-right">

              {% if user.is_authenticated %}

                <li><a>Hello, {{ user.username }}.</a></li>

                <li><a href="{% url 'users:logout' %}">log out</a></li>

              {% else %}

                <li><a href="{% url 'users:register' %}">register</a></li>

                <li><a href="{% url 'users:login' %}">log in</a></li>

              {% endif %}

           </ul>

          </div><!--/.nav-collapse -->

 

        </div>

      </nav>

 

 

 

 

 

 

 

 

第一個元素為起始標籤<body> HTML檔的主體包含使用者將在頁面上看到的內容。處是一個<nav> 元素,表示頁面的導航連結部分。對於這個元素內的所有內容,都將根據選擇器 selectornavbar navbar-default navbar-static-top 定義的Bootstrap樣式規則來設置樣式。選擇器決定了特定樣式規則將應用於頁面上的哪些元素。

處,這個範本定義了一個按鈕,它將在流覽器視窗太窄、無法水準顯示整個巡覽列時顯示出來。如果使用者按一下這個按鈕,將出現一個下拉清單,其中包含所有的導航元素。在使用者縮小流覽器視窗或在螢幕較小的移動設備上顯示網站時,collapse 會使巡覽列折疊起來。

處,我們在巡覽列的最左邊顯示專案名,並將其設置為到主頁的連結,因為它將出現在這個專案的每個頁面中。

處,我們定義了一組讓用戶能夠在網站中導航的連結。巡覽列其實就是一個以<ul> 打頭的列表(見),其中每個連結都是一個清單項(<li> )。要添加更多的連結,可插入更多使用下述結構的行:

 

<li><a href="{% url 'learning_logs:title' %}">Title</a></li>

 

 

 

 

 

 

 

 

這行表示巡覽列中的一個連結。這個連結是直接從base.html的前一個版本中複製而來的。

處,我們添加了第二個導航連結清單,這裡使用的選擇器為navbar-right 。選擇器navbar-right 設置一組連結的樣式,使其出現在巡覽列右邊——登錄連結和註冊連結通常出現在這裡。在這裡,我們要麼顯示問候語和登出連結,要麼顯示註冊連結和登錄連結。這部分餘下的代碼結束包含巡覽列的元素(見

3. 定義頁面的主要部分

base.html的剩餘部分包含頁面的主要部分:

 

  --snip--

      </nav>

 

     <div class="container">

 

        <div class="page-header">

         {% block header %}{% endblock header %}

        </div>

        <div>

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

        </div>

 

      </div> <!-- /container -->

 

    </body>

  </html>

 

 

 

 

 

 

 

 

處是一個<div> 起始標籤,其class屬性為container div是網頁的一部分,可用於任何目的,並可通過邊框、元素周圍的空間(外邊距)、內容和邊框之間的間距(內邊距)、背景色和其他樣式規則來設置其樣式。這個div是一個容器,其中包含兩個元素:一個新增的名為header 的塊(見)以及我們在第18章使用的content 塊(見)。header 塊的內容告訴使用者頁面包含哪些資訊以及使用者可在頁面上執行哪些操作;其class屬性值page-header 將一系列樣式應用於這個塊。content 塊是一個獨立的div,未使用class屬性指定樣式。

如果你在流覽器中載入學習筆記的主頁,將看到一個類似於圖20-1所示的專業級巡覽列。請嘗試調整視窗的大小,使其非常窄;此時巡覽列將變成一個按鈕,如果你按一下這個按鈕,將打開一個下拉清單,其中包含所有的導航連結。

注意  這個簡化的Bootstrap範本適用於最新的流覽器,而較早的流覽器可能不能正確地渲染某些樣式。完整的範本可在http://getbootstrap.com/getting-started/#examples/ 找到,它幾乎在所有流覽器中都管用。

20.1.4 使用jumbotron設置主頁的樣式

下面來使用新定義的header 塊及另一個名為jumbotronBootstrap元素修改主頁。jumbotron元素是一個大框,相比於頁面的其他部分顯得鶴立雞群,你想在其中包含什麼東西都可以;它通常用於在主頁中呈現項目的簡要描述。我們還可以修改主頁顯示的消息。index.html的代碼如下:

index.html

 

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

 

{% block header %}

   <div class='jumbotron'>

      <h1>Track your learning.</h1>

    </div>

  {% endblock header %}

 

  {% block content %}

   <h2>

      <a href="{% url 'users:register' %}">Register an account</a> to make

      your own Learning Log, and list the topics you're learning about.

    </h2>

    <h2>

      Whenever you learn something new about a topic, make an entry

      summarizing what you've learned.

    </h2>

  {% endblock content %}

 

 

 

 

 

 

 

 

處,我們告訴Django,我們要定義header 塊包含的內容。在一個jumbotron 元素(見)中,我們放置了一條簡短的標語——Track your Learning,讓首次訪問者大致知道學習筆記是做什麼用的。

處,我們通過添加一些文本,做了更詳細的說明。我們邀請用戶建立帳戶,並描述了用戶可執行的兩種主要操作:添加新主題以及在主題中創建條目。現在的主頁類似於圖20-1所示,與設置樣式前相比,有了很大的改進。

20.1.5 設置登錄頁面的樣式

我們改進了登錄頁面的整體外觀,但還未改進登錄表單,下面來讓表單與頁面的其他部分一致:

login.html

 

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

{% load bootstrap3 %}

 

{% block header %}

    <h2>Log in to your account.</h2>

  {% endblock header %}

 

  {% block content %}

 

   <form method="post" action="{% url 'users:login' %}" class="form">

      {% csrf_token %}

     {% bootstrap_form form %}

 

     {% buttons %}

        <button name="submit" class="btn btn-primary">log in</button>

      {% endbuttons %}

 

      <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />

    </form>

 

  {% endblock content %}

 

 

 

 

 

 

 

 

處,我們在這個範本中載入了bootstrap3範本標籤。在處,我們定義了header 塊,它描述了這個頁面是做什麼用的。注意,我們從這個範本中刪除了{% if form.errors %} 代碼塊,因為django-bootstrap3會自動管理表單錯誤。

處,我們添加了屬性class="form" ;然後使用範本標籤{% bootstrap_form %} 來顯示表單(見);這個標籤替換了我們在第19章使用的標籤{{ form.as_p }} 。範本標籤{% booststrap_form %} Bootstrap樣式規則應用于各個表單元素。處是bootstrap3起始範本標籤{% buttons %} ,它將Bootstrap樣式應用于按鈕。

20-2顯示了現在渲染的登錄表單。這個頁面比以前整潔得多,其風格一致,用途明確。如果你嘗試使用錯誤的用戶名或密碼登錄,將發現消息的樣式與整個網站也是一致的,毫無違和感。


20-2 使用Bootstrap設置樣式後的登錄頁面

20.1.6 設置new_topic 頁面的樣式

下面來讓其他網頁的風格也一致。首先來修改new_topic 頁面

new_topic.html

 

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

  {% load bootstrap3 %}

 

{% block header %}

    <h2>Add a new topic:</h2>

  {% endblock header %}

 

  {% block content %}

 

   <form action="{% url 'learning_logs:new_topic' %}" method='post'

        class="form">

 

      {% csrf_token %}

     {% bootstrap_form form %}

 

     {% buttons %}

        <button name="submit" class="btn btn-primary">add topic</button>

      {% endbuttons %}

 

    </form>

 

  {% endblock content %}

 

 

 

 

 

 

 

 

這裡的大多數修改都類似於對login.html所做的修改:在處載入bootstrap3,添加header 塊並在其中包含合適的消息;接下來,我們在標籤<form> 中添加屬性class="form" (見),使用範本標籤{% bootstrap_form %} 代替{{ form.as_p }} (見),並使用bootstrap3結構來定義提交按鈕(見)。如果你現在登錄並導航到new_topic 頁面,將發現其外觀類似於登錄頁面。

20.1.7 設置topics頁面的樣式

下面來確保用於查看資訊的頁面的樣式也是合適的,首先來設置topics頁面的樣式:

topics.html

 

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

 

{% block header %}

    <h1>Topics</h1>

  {% endblock header %}

 

  {% block content %}

 

    <ul>

      {% for topic in topics %}

        <li>

         <h3>

            <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>

          </h3>

        </li>

      {% empty %}

        <li>No topics have been added yet.</li>

      {% endfor %}

    </ul>

 

   <h3><a href="{% url 'learning_logs:new_topic' %}">Add new topic</h3>

 

  {% endblock content %}

 

 

 

 

 

 

 

 

我們不需要標籤{% load bootstrap3 %} ,因為我們在這個檔中沒有使用任何bootstrap3自訂標籤。我們在header 塊中添加了標題Topics(見)。為設置每個主題的樣式,我們將它們都設置為<h3> 元素,讓它們在頁面上顯得大些(見);對於添加新主題的連結,也做了同樣的處理(見

20.1.8 設置topic頁面中條目的樣式

topic頁面包含的內容比其他大部分頁面都多,因此需要做的樣式設置工作要多些。我們將使用Bootstrap面板 panel)來突出每個條目。面板是一個帶預定義樣式的div,非常適合用於顯示主題的條目:

topic.html

 

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

 

{% block header %}

    <h2>{{ topic }}</h2>

  {% endblock header %}

 

  {% block content %}

    <p>

      <a href="{% url 'learning_logs:new_entry' topic.id %}">add new entry</a>

    </p>

 

    {% for entry in entries %}

     <div class="panel panel-default">

       <div class="panel-heading">

         <h3>

            {{ entry.date_added|date:'M d, Y H:i' }}

           <small>

              <a href="{% url 'learning_logs:edit_entry' entry.id %}">

                edit entry</a>

            </small>

          </h3>

        </div>

       <div class="panel-body">

          {{ entry.text|linebreaks }}

        </div>

      </div> <!-- panel -->

    {% empty %}

      There are no entries for this topic yet.

    {% endfor %}

 

  {% endblock content %}

 

 

 

 

 

 

 

 

我們首先將主題放在了header 塊中(見)。然後,我們刪除了這個範本中以前使用的無序列表結構。在處,我們創建了一個面板式div元素(而不是將每個條目作為一個列表項),其中包含兩個嵌套的div:一個面板標題(panel-heading div(見)和一個面板主體(panel-body div(見)。其中面板標題div包含條目的創建日期以及用於編輯條目的連結,它們都被設置為<h3> 元素,而對於編輯條目的連結,還使用了標籤<small> ,使其比時間戳記小些(見

處是面板主體div,其中包含條目的實際文本。注意,只修改了影響頁面外觀的元素,對在頁面中包含資訊的Django代碼未做任何修改。

20-3顯示了修改後的topic頁面。學習筆記的功能沒有任何變化,但顯得更專業了,對用戶會更有吸引力。


20-3 使用Bootstrap設置樣式後的topic頁面

注意  要使用其他Bootstrap範本,可採用與本章類似的流程:將這個範本複製到base.html中,並修改包含實際內容的元素,以使用該範本來顯示專案的資訊;然後,使用Bootstrap的樣式設置工具來設置各個頁面中內容的樣式。

 

動手試一試

20-1 其他表單 :我們對登錄頁面和add_topic 頁面應用了Bootstrap樣式。請對其他基於表單的頁面做類似的修改:new_entry 頁面、edit_entry 頁面和註冊頁面。

20-2 設置博客的樣式 :對於你在第19章創建的專案Blog,使用Bootstrap來設置其樣式。

20.2 部署學習筆記

至此,專案學習筆記的外觀顯得很專業了,下面來將其部署到一台伺服器,讓任何有網路連接的人都能夠使用它。為此,我們將使用Heroku,這是一個基於Web的平臺,讓你能夠管理Web應用程式的部署。我們將讓學習筆記Heroku上運行。

Windows系統上的部署過程與在LinuxOS X系統上稍有不同。如果你使用的是Windows,請閱讀各節的注意,它們指出了在Windows系統上需要採取的不同做法。

20.2.1 建立Heroku帳戶

要建立帳戶,請訪問https://heroku.com/ ,並按一下其中的一個註冊連結。註冊帳戶是免費的,Heroku提供了免費試用服務,讓你能夠將專案部署到伺服器並對其進行測試。

注意  Heroku提供的免費試用服務存在一些限制,如可部署的應用程式數量以及使用者訪問應用程式的頻率。但這些限制都很寬鬆,讓你完全能夠在不支付任何費用的情況下練習部署應用程式。

20.2.2 安裝Heroku Toolbelt

要將專案部署到Heroku的伺服器並對其進行管理,需要使用Heroku Toolbelt提供的工具。要安裝最新的Heroku Toolbelt版本,請訪問https://toolbelt.heroku.com/ ,並根據你使用的作業系統按相關的說明做:使用只包含一行的終端命令,或下載並運行安裝程式。

20.2.3 安裝必要的包

你還需安裝很多包,以幫助在伺服器上支援Django專案提供的服務。為此,在活動的虛擬環境中執行如下命令:

 

(ll_env)learning_log$ pip install dj-database-url

(ll_env)learning_log$ pip install dj-static

(ll_env)learning_log$ pip install static3

(ll_env)learning_log$ pip install gunicorn

 

 

 

 

 

 

 

 

務必逐個地執行這些命令,這樣你就能知道哪些包未能正確地安裝。dj-database-url 包説明DjangoHeroku使用的資料庫進行通信,dj-static static3 包説明Django正確地管理靜態檔,而gunicorn 是一個伺服器軟體,能夠在線上環境中支援應用程式提供的服務。(靜態檔包括樣式規則和JavaScript檔。)

注意  在Windows系統中,有些必不可少的包可能無法安裝,因此如果在你嘗試安裝有些這樣的包時出現錯誤消息,也不用擔心。重要的是讓Heroku在部署中安裝這些包,下一節就將這樣做。

20.2.4 創建包含包列表的檔requirements.txt

Heroku需要知道我們的專案依賴于哪些包,因此我們將使用pip來生成一個檔,其中列出了這些包。同樣,進入活動虛擬環境,並執行如下命令:

 

(ll_env)learning_log$ pip freeze > requirements.txt

 

 

 

 

 

 

 

 

命令freeze pip將專案中當前安裝的所有包的名稱都寫入到檔requirements.txt中。請打開文件requirements.txt,查看項目中安裝的包及其版本(如果你使用的是Windows系統,看到的內容可能不全):

requirements.txt

 

Django==1.8.4

dj-database-url==0.3.0

dj-static==0.0.6

django-bootstrap3==6.2.2

gunicorn==19.3.0

static3==0.6.1

 

 

 

 

 

 

 

 

學習筆記依賴於6個特定版本的包,因此需要在相應的環境中才能正確地運行。我們部署學習筆記時,Heroku將安裝requirements.txt列出的所有包,從而創建一個環境,其中包含我們在本地使用的所有包。有鑑於此,我們可以信心滿滿,深信項目部署到Heroku後,行為將與它在本地系統上的完全相同。當你在自己的系統上開發並維護各種專案時,這將是一個巨大的優點。

接下來,我們需要在包清單中添加psycopg2 ,它説明Heroku管理活動資料庫。為此,打開檔requirements.txt,並添加代碼行psycopg2>=2.6.1 。這將安裝2.6.1版的psycopg2——如果有更高的版本,則安裝更高的版本:

requirements.txt

 

Django==1.8.4

dj-database-url==0.3.0

dj-static==0.0.6

django-bootstrap3==6.2.2

gunicorn==19.3.0

static3==0.6.1

psycopg2>=2.6.1

 

 

 

 

 

 

 

 

如果有必不可少的包在你的系統中沒有安裝,請將其添加到檔requirements.txt中。最終的檔requirements.txt應包含上面列出的每個包。如果在你的系統中,requirements.txt列出的包的版本與上面列出的不同,請保留原來的版本號。

注意  如果你使用的是Windows系統,請確保檔requirements.txt的內容與前面列出的一致,而不要管你在系統中能夠安裝哪些包。

20.2.5 指定Python版本

如果你沒有指定Python版本,Heroku將使用其當前的Python默認版本。下面來確保Heroku使用我們使用的Python版本。為此,在活動的虛擬環境中,執行命令python --version 

 

(ll_env)learning_log$ python --version

Python 3.5.0

 

 

 

 

 

 

 

 

上面的輸出表明,我使用的是Python 3.5.0。請在manage.py所在的資料夾中新建一個名為runtime.txt的檔,並在其中輸入如下內容:

runtime.txt

 

python-3.5.0

 

 

 

 

 

 

 

 

這個檔應只包含一行內容,以上面所示的格式指定了你使用的Python版本;請確保輸入小寫的python ,在它後面輸入一個連字號,再輸入由三部分組成的版本號。

注意  如果出現錯誤消息,指出不能使用你指定的Python版本,請訪問https://devcenter.heroku.com/ 並按一下Python,再按一下連結Specifying a Python Runtime。流覽打開的文章,瞭解支援的Python版本,並使用與你使用的Python版本最接近的版本。

20.2.6 為部署到Herohu而修改settings.py

現在需要在settings.py末尾添加一個片段,在其中指定一些Heroku環境設置:

settings.py

 

  --snip--

  # django-bootstrap3設置

  BOOTSTRAP3 = {

      'include_jquery': True,

      }

 

  # Heroku設置

if os.getcwd() == '/app':

     import dj_database_url

      DATABASES = {

          'default': dj_database_url.config(default='postgres://localhost')

      }

 

      # request.is_secure()承認X-Forwarded-Proto

     SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

 

      # 支援所有的主機頭(host header

     ALLOWED_HOSTS = ['*']

 

      # 靜態資產配置

     BASE_DIR = os.path.dirname(os.path.abspath(__file__))

      STATIC_ROOT = 'staticfiles'

      STATICFILES_DIRS = (

          os.path.join(BASE_DIR, 'static'),

      )

 

 

 

 

 

 

 

 

處,我們使用了函數getcwd() ,它獲取當前的工作目錄 (當前運行的檔所在的目錄)。在Heroku部署中,這個目錄總是/app。在本地部署中,這個目錄通常是專案檔案夾的名稱(就我們的項目而言,為learning_log)。這個if 測試確保僅當項目被部署到Heroku時,才運行這個代碼塊。這種結構讓我們能夠將同一個設置檔用於本地開發環境和線上伺服器。

處,我們導入了dj_database_url ,用於在Heroku上配置伺服器。Heroku使用PostgreSQL(也叫Postgres——一種比SQLite更高級的資料庫;這些設置對專案進行配置,使其在Heroku上使用Postgres資料庫。其他設置的作用分別如下:支持HTTPS請求(見);Django能夠使用HerokuURL來提供專案提供的服務(見);設置專案,使其能夠在Heroku上正確地提供靜態檔(見

20.2.7 創建啟動進程的Procfile

Procfile告訴Heroku啟動哪些進程,以便能夠正確地提供專案提供的服務。這個檔只包含一行,你應將其命名為Procfile(其中的P為大寫),不指定檔副檔名,並保存到manage.py所在的目錄中。

Procfile的內容如下:

Procfile

 

web: gunicorn learning_log.wsgi --log-file -

 

 

 

 

 

 

 

 

這行代碼讓Herokugunicorn用作伺服器,並使用learning_log/wsgi.py中的設置來啟動應用程式。標誌log-file 告訴Heroku應將哪些類型的事件寫入日誌。

20.2.8 為部署到Herohu而修改wsgi.py

為部署到Heroku,我們還需修改wsgi.py,因為Heroku需要的設置與我們一直在使用的設置稍有不同:

wsgi.py

 

--snip--

import os

 

from django.core.wsgi import get_wsgi_application

from dj_static import Cling

 

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "learning_log.settings")

application = Cling(get_wsgi_application())

 

 

 

 

 

 

 

 

我們導入了説明正確地提供靜態檔的Cling,並使用它來啟動應用程式。這些代碼在本地也適用,因此無需將其放在if 代碼塊內。

20.2.9 創建用於存儲靜態檔的目錄

Heroku上,Django搜集所有的靜態檔,並將它們放在一個地方,以便能夠高效地管理它們。我們將創建一個用於存儲這些靜態檔的目錄。在資料夾learning_log中,有一個名稱也為learning_log的子資料夾。在這個子資料夾中,新建一個名為static的資料夾,因此這個資料夾的路徑為learning_log/learning_log/static/。我們還需在這個資料夾中創建一個占位檔,因為項目被推送到Heroku時,它將不會包含原來為空的資料夾。在目錄static/中,創建一個名為placeholder.txt的文件:

placeholder.txt

 

This file ensures that learning_log/static/ will be added to the project.

Django will collect static files and place them in learning_log/static/.

 

 

 

 

 

 

 

 

上述內容沒有什麼特別之處,只是指出了在項目中添加這個檔的原因。

20.2.10 在本地使用gunicorn伺服器

如果你使用的是LinuxOS X,可在部署到Heroku前嘗試在本地使用gunicorn伺服器。為此,在活動的虛擬環境中,執行命令heroku local 以啟動Procfile指定的進程:

 

  (ll_env)learning_log$ heroku local

  Installing Heroku Toolbelt v4... done

  --snip--

  forego | starting web.1 on port 5000

web.1  | [2015-08-13 22:00:45 -0800] [12875] [INFO] Starting gunicorn 19.3.0

web.1  | [2015-08-13 22:00:45 -0800] [12875] [INFO] Listening at:

      http://0.0.0.0:5000 (12875)

web.1  | [2015-08-13 22:00:45 -0800] [12878] [INFO] Booting worker with pid: 12878

 

 

 

 

 

 

 

 

首次執行命令heroku local 時,將安裝Heroku Toolbelt中的很多包。這裡的輸出表明啟動了gunicorn,其進程id12875(見)。處的輸出表明,gunicorn在埠5000上偵聽請求。另外,gunicorn還啟動了一個工作進程(12878),用於説明處理請求(見

為確認一切運行正常,請訪問http://localhost:5000/,你將看到學習筆記的主頁,就像使用Django伺服器(runserver)時一樣。為停止heroku local 啟動的進程,請按Ctrl + C,你將在本地開發中繼續使用runserver 

注意  gunicorn不能在Windows系統上運行,因此如果你使用的是Windows系統,請跳過這一步。但這不會影響你將項目部署到Heroku

20.2.11 使用Git跟蹤專案檔案

如果你閱讀完了第17章,就知道Git是一個版本控制程式,讓你能夠在每次成功實現新功能後都拍攝項目代碼的快照。無論出現什麼問題(如實現新功能時不小心引入了bug),你都可以輕鬆地恢復到最後一個可行的快照。每個快照都被稱為提交 

使用Git意味著你在試著實現新功能時無需擔心破壞項目。將專案部署到伺服器時,需要確保部署的是可行版本。如果你想更詳細地瞭解Git和版本控制,請參閱附錄D

1. 安裝Git

Heroku Toolbelt包含Git,因此它應該已經安裝到了你的系統中。然而,在安裝Heroku Toolbelt之前打開的終端視窗中無法訪問Git,因此請打開一個新的終端視窗,並在其中執行命令git --version 

 

(ll_env)learning_log$ git --version

git version 2.5.0

 

 

 

 

 

 

 

 

如果由於某種原因出現了錯誤消息,請參閱附錄D中的Git安裝說明。

2. 配置Git

Git跟蹤誰修改了專案,即便專案由一個人開發時亦如此。為進行跟蹤,Git需要知道你的用戶名和email。因此,你必須提供用戶名,但對於練習項目,可隨便偽造一個email

 

(ll_env)learning_log$ git config --global user.name "ehmatthes"

(ll_env)learning_log$ git config --global user.email "eric@example.com"

 

 

 

 

 

 

 

 

如果你忘記了這一步,當你首次提交時,Git將提示你提供這些資訊。

3. 忽略文件

我們無需讓Git跟蹤項目中的每個檔,因此將讓Git忽略一些檔。為此,在manage.py所在的資料夾中創建一個名為.gitignore的文件。注意,這個檔案名以句點打頭,且不包含副檔名。在這個檔中輸入如下內容:

.gitignore

 

ll_env/

__pycache__/

*.sqlite3

 

 

 

 

 

 

 

 

我們讓Git忽略目錄llenv,因為我們隨時都可以自動重新創建它。我們還指定不跟蹤目錄 \ _pycache__,這個目錄包含Django運行.py檔時自動創建的.pyc文件。我們沒有跟蹤對本地資料庫的修改,因為這是一個糟糕的做法:如果你在伺服器上使用的是SQLite,當你將項目推送到伺服器時,可能會不小心用本地測試資料庫覆蓋線上資料庫。

注意  如果你使用的是Python 2.7,請將_pycache_ 替換為*.pyc ,因為Python 2.7不會創建目錄__pycache__

4. 提交專案

我們需要為學習筆記初始化一個Git倉庫,將所有必要的檔都加入到這個倉庫中,並提交專案的初始狀態,如下所示:

 

(ll_env)learning_log$ git init

  Initialized empty Git repository in /home/ehmatthes/pcc/learning_log/.git/

(ll_env)learning_log$ git add .

(ll_env)learning_log$ git commit -am "Ready for deployment to heroku."

  [master (root-commit) dbc1d99] Ready for deployment to heroku.

   43 files changed, 746 insertions(+)

   create mode 100644 .gitignore

   create mode 100644 Procfile

   --snip--

   create mode 100644 users/views.py

(ll_env)learning_log$ git status

  # On branch master

  nothing to commit, working directory clean

  (ll_env)learning_log$

 

 

 

 

 

 

 

 

處,我們執行命令git init ,在學習筆記所在的目錄中初始化一個空倉庫。在處,我們執行了命令git add . (千萬別忘了這個句點),它將未被忽略的檔都添加到這個倉庫中。在處,我們執行了命令git commit -am commit message ,其中的標誌-a Git在這個提交中包含所有修改過的檔,而標誌-m Git記錄一條日誌消息。

處,我們執行了命令git status ,輸出表明當前位於分支master中,而工作目錄是乾淨 clean)的。每當你要將項目推送到Heroku時,都希望看到這樣的狀態。

20.2.12 推送到Heroku

我們終於為將項目推送到Heroku做好了準備。在活動的虛擬環境中,執行下面的命令:

 

(ll_env)learning_log$ heroku login

  Enter your Heroku credentials.

  Email: eric@example.com

  Password (typing will be hidden):

  Logged in as eric@example.com

(ll_env)learning_log$ heroku create

  Creating afternoon-meadow-2775... done, stack is cedar-14

  https://afternoon-meadow-2775.herokuapp.com/ |

      https://git.heroku.com/afternoon-meadow-2775.git

  Git remote heroku added

(ll_env)learning_log$ git push heroku master

  --snip--

  remote: -----> Launching... done, v6

remote:        https://afternoon-meadow-2775.herokuapp.com/ deployed to Heroku

  remote: Verifying deploy.... done.

  To https://git.heroku.com/afternoon-meadow-2775.git

     bdb2a35..62d711d  master -> master

  (ll_env)learning_log$

 

 

 

 

 

 

 

 

首先,在終端會話中,使用你在https://heroku.com/ 創建帳戶時指定的用戶名和密碼來登錄Heroku(見)。然後,Heroku創建一個空項目(見)。Heroku生成的項目名由兩個單詞和一個數字組成,你以後可修改這個名稱。接下來,我們執行命令git push heroku master (見),它Git將專案的分支master推送到Heroku剛才創建的倉庫中;Heroku隨後使用這些檔在其伺服器上創建專案。處列出了用於訪問這個項目的URL

執行這些命令後,專案就部署好了,但還未對其做全面的配置。為核實正確地啟動了伺服器進程,請執行命令heroku ps 

 

  (ll_env)learning_log$ heroku ps

Free quota left: 17h 40m

=== web (Free): `gunicorn learning_log.wsgi __log-file -`

  web.1: up 2015/08/14 07:08:51 (~ 10m ago)

  (ll_env)learning_log$

 

 

 

 

 

 

 

 

輸出指出了在接下來的24小時內,項目還可在多長時間內處於活動狀態(見)。編寫本書時,Heroku允許免費部署在24小時內最多可以有18小時處於活動狀態。專案的活動時間超過這個限制後,將顯示標準的伺服器錯誤頁面,稍後我們將設置這個錯誤頁面。在處,我們發現啟動了Procfile指定的進程。

現在,我們可以使用命令heroku open 在流覽器中打開這個應用程式了:

 

(ll_env)learning_log$ heroku open

Opening afternoon-meadow-2775... done

 

 

 

 

 

 

 

 

你也可以啟動流覽器並輸入Heroku告訴你的URL,但上述命令可實現同樣的結果。你將看到學習筆記的主頁,其樣式設置正確無誤,但你還無法使用這個應用程式,因為我們還沒有建立資料庫。

注意  部署到Heroku的流程會不斷變化。如果你遇到無法解決的問題,請通過查看Heroku文檔來獲取幫助。為此,可訪問https://devcenter.heroku.com/ ,按一下Python,再按一下連結Getting Started with Django。如果你看不懂這些文檔,請參閱附錄C提供的建議。

20.2.13 在Heroku上建立資料庫

為建立線上資料庫,我們需要再次執行命令migrate ,並應用在開發期間生成的所有遷移。要對Heroku專案執行DjangoPython命令,可使用命令heroku run 。下面演示了如何對Heroku部署執行命令migrate 

 

(ll_env)learning_log$ heroku run python manage.py migrate

Running `python manage.py migrate` on afternoon-meadow-2775... up, run.2435

    --snip--

Running migrations:

    --snip--

    Applying learning_logs.0001_initial... OK

    Applying learning_logs.0002_entry... OK

    Applying learning_logs.0003_topic_user... OK

    Applying sessions.0001_initial... OK

  (ll_env)learning_log$

 

 

 

 

 

 

 

 

我們首先執行了命令heroku run python manage.py migrate (見);Heroku隨後創建一個終端會話來執行命令migrate (見)。在處,Django應用默認遷移以及我們在開發學習筆記期間生成的遷移。

現在如果你訪問這個部署的應用程式,將能夠像在本地系統上一樣使用它。然而,你看不到你在本地部署中輸入的任何資料,因為它們沒有複製到線上伺服器。一種通常的做法是不將本地資料複製到線上部署中,因為本地資料通常是測試資料。

你可以分享學習筆記Heroku URL,讓任何人都可以使用它。在下一節,我們將再完成幾個任務,以結束部署過程並讓你能夠繼續開發學習筆記

20.2.14 改進Heroku部署

在本節中,我們將通過創建超級用戶來改進部署,就像在本地一樣。我們還將讓這個項目更安全:將DEBUG 設置為False ,讓使用者在錯誤消息中看不到額外的資訊,以防他們使用這些資訊來攻擊伺服器。

1. Heroku上創建超級用戶

我們知道可使用命令heroku run 來執行一次性命令,但也可這樣執行命令:在連接到了Heroku伺服器的情況下,使用命令heroku run bash 來打開Bash終端會話。Bash是眾多Linux終端運行的語言。我們將使用Bash終端會話來創建超級使用者,以便能夠訪問線上應用程式的管理網站:

 

  (ll_env)learning_log$ heroku run bash

  Running `bash` on afternoon-meadow-2775... up, run.6244

~ $ ls

  learning_log learning_logs manage.py Procfile requirements.txt runtime.txt users

  staticfiles

~ $ python manage.py createsuperuser

  Username (leave blank to use 'u41907'): ll_admin

  Email address:

  Password:

  Password (again):

  Superuser created successfully.

~ $ exit

  exit

  (ll_env)learning_log$

 

 

 

 

 

 

 

 

處,我們執行命令ls ,以查看伺服器上有哪些檔和目錄;伺服器包含的檔和目錄應該與本地系統相同。你可以像遍歷其他檔案系統一樣遍歷這個檔案系統。

注意  即便你使用的是Windows系統,也應使用這裡列出的命令(如ls 而不是dir ),因為你正通過遠端連接運行一個Linux終端。

處,我們執行了創建超級用戶的命令,它像第18章在本地系統創建超級使用者一樣提示你輸入相關的資訊。在這個終端會話中創建超級使用者後,使用命令exit 返回到本地系統的終端會話(見

現在,你可以在線上應用程式的URL末尾添加/admin/來登錄管理網站了。對我而言,這個URLhttps://afternoon-meadow-2775.herokuapp.com/admin/ 

如果已經有其他人開始使用這個項目,別忘了你可以訪問他們的所有資料!千萬別不把這當回事,否則用戶就不會再將其資料託付給你了。

2. Heroku上創建對用戶友好的URL

你可能希望URL更友好,比https://afternoon-meadow-2775.herokuapp.com/ 更好記。為此,可只需使用一個命令來重命名應用程式:

 

(ll_env)learning_log$ heroku apps:rename learning-log

Renaming afternoon-meadow-2775 to learning-log... done

https://learning-log.herokuapp.com/ | https://git.heroku.com/learning-log.git

Git remote heroku updated

(ll_env)learning_log$

 

 

 

 

 

 

 

 

給應用程式命名時,可使用字母、數位和連字號;你想怎麼命名應用程式都可以,只要指定的名稱未被別人使用就行。現在,項目的URL變成了https://learning-log.herokuapp.com/ ;使用以前的URL再也無法訪問它,命令apps:rename 將整個項目都移到了新的URL處。

注意  你使用Heroku提供的免費服務來部署專案時,如果項目在指定的時間內未收到請求或過於活躍,Heroku將讓專案進入休眠狀態。使用者初次訪問處於休眠狀態的網站時,載入時間將更長,但對於後續請求,伺服器的回應速度將更快。這就是Heroku能夠提供免費部署的原因所在。

20.2.15 確保專案的安全

當前,我們部署的項目存在一個嚴重的安全問題:settings.py包含設置DEBUG=True ,它在發生錯誤時顯示調試資訊。開發專案時,Django的錯誤頁面向你顯示了重要的調試資訊,如果將專案部署到伺服器後依然保留這個設置,將給攻擊者提供大量可供利用的資訊。我們還需確保任何人都無法看到這些資訊,也不能冒充專案託管網站來重定向請求。

下面來修改settings.py,以讓我們能夠在本地看到錯誤消息,但部署到伺服器後不顯示任何錯誤消息:

settings.py

 

  --snip--

  # Heroku設置

  if os.getcwd() == '/app':

      --snip--

      # request.is_secure()承認X-Forwarded-Proto

      SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

 

      # 只允許Heroku託管這個項目

     ALLOWED_HOSTS = ['learning-log.herokuapp.com']

 

     DEBUG = False

 

      # 靜態資產配置

      --snip--

 

 

 

 

 

 

 

 

我們只需做兩方面的修改。在處,修改ALLOWED_HOSTS ,只允許Heroku託管這個項目。你需要使用應用程式的名稱,可以是Heroku提供的名稱(如afternoon-meadow-2775.herokuapp.com),也可以是你選擇的名稱。在處,我們將DEBUG 設置為False ,讓Django不在錯誤發生時顯示敏感資訊。

20.2.16 提交並推送修改

現在需要將對settings.py所做的修改提交到Git倉庫,再將修改推送到Heroku。下面的終端會話演示了這個過程:

 

(ll_env)learning_log$ git commit -am "Set DEBUG=False for Heroku."

  [master 081f635] Set DEBUG=False for Heroku.

   1 file changed, 4 insertions(+), 2 deletions(-)

(ll_env)learning_log$ git status

  # On branch master

  nothing to commit, working directory clean

  (ll_env)learning_log$

 

 

 

 

 

 

 

 

我們執行命令git commit ,並指定了一條簡短而具有描述性的提交消息(見)。別忘了,標誌-am Git提交所有修改過的檔,並記錄一條日誌消息。Git找出唯一一個修改過的檔,並將所做的修改提交到倉庫。

處顯示的狀態表明我們在倉庫的分支master上工作,當前沒有任何未提交的修改。推送到Heroku之前,必須檢查狀態並看到剛才所說的消息。如果你沒有看到這樣的消息,說明有未提交的修改,而這些修改將不會推送到伺服器。在這種情況下,可嘗試再次執行命令commit ,但如果你不知道該如何解決這個問題,請閱讀附錄D,更深入地瞭解Git的用法。

下面來將修改後的倉庫推送到Heroku

 

(ll_env)learning_log$ git push heroku master

--snip--

remote: -----> Python app detected

remote: -----> Installing dependencies with pip

--snip--

remote: -----> Launching... done, v8

remote:        https://learning-log.herokuapp.com/ deployed to Heroku

remote: Verifying deploy.... done.

To https://git.heroku.com/learning-log.git

   4c9d111..ef65d2b  master -> master

(ll_env)learning_log$

 

 

 

 

 

 

 

 

Heroku發現倉庫發生了變化,因此重建專案,確保所有的修改都已生效。它不會重建資料庫,因此這次無需執行命令migrate 

現在要核實部署更安全了,請輸入項目的URL,並在末尾加上我們未定義的擴展。例如,嘗試訪問http://learning-log.herokuapp.com/letmein/ 。你將看到一個通用的錯誤頁面,它沒有洩露任何有關該專案的具體資訊。如果你嘗試向本地的學習筆記發出同樣的請求——輸入URL http://localhost:8000/letmein/,你將看到完整的Django錯誤頁面。這樣的結果非常理想,你接著開發這個專案時,將看到資訊豐富的錯誤消息,但使用者看不到有關專案代碼的重要資訊。

20.2.17 創建自訂錯誤頁面

在第19章,我們對學習筆記進行了配置,使其在使用者請求不屬於他的主題或條目時返回404錯誤。你可能還遇到過一些500錯誤(內部錯誤)。404錯誤通常意味著你的Django代碼是正確的,但請求的物件不存在。500錯誤通常意味著你編寫的代碼有問題,如views.py中的函數有問題。當前,在這兩種情況下,Django都返回通用的錯誤頁面,但我們可以編寫外觀與學習筆記一致的404500錯誤頁面範本。這些範本必須放在根範本目錄中。

1. 創建自訂範本

在資料夾learning_log/learning_log中,新建一個資料夾,並將其命名為templates;再在這個資料夾中新建一個名為404.html的檔,並在其中輸入如下內容:

404.html

 

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

 

{% block header %}

    <h2>The item you requested is not available. (404)</h2>

{% endblock header %}

 

 

 

 

 

 

 

 

這個簡單的範本指定了通用的404錯誤頁面包含的資訊,並且該頁面的外觀與網站的其他部分一致。

再創建一個名為500.html的檔,並在其中輸入如下代碼:

500.html

 

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

 

{% block header %}

    <h2>There has been an internal error. (500)</h2>

{% endblock header %}

 

 

 

 

 

 

 

 

這些新檔要求對settings.py做細微的修改:

settings.py

 

--snip--

TEMPLATES = [

    {

        'BACKEND': 'django.template.backends.django.DjangoTemplates',

        'DIRS': [os.path.join(BASE_DIR, 'learning_log/templates')],

        'APP_DIRS': True,

        --snip--

    },

]

--snip--

 

 

 

 

 

 

 

 

這項修改讓Django在根範本目錄中查找錯誤頁面範本。

2. 在本地查看錯誤頁面

在將項目推送到Heroku之前,如果你要在本地查看錯誤頁面是什麼樣的,首先需要在本地設置中設置Debug=False ,以禁止顯示預設的Django調試頁面。為此,可對settings.py做如下修改(請確保你修改的是用於本地環境的settings.py部分,而不是用於Heroku的部分):

settings.py

 

--snip--

# 安全警告:不要在線上環境中啟用調試!

DEBUG = False

 

ALLOWED_HOSTS = ['localhost']

--snip--

 

 

 

 

 

 

 

 

DEBUG 被設置為False 時,你必須在ALLOWED_HOSTS 中指定一個主機。現在,請求一個不屬於你的主題或條目,以查看404錯誤頁面;請求不存在的URL(如localhost:8000/letmein/),以查看500錯誤頁面。

查看錯誤頁面後,將DEBUG 重新設置為True ,以方便你進一步開發學習筆記。(在settings.py中用於Heroku部署的部分中,確保DEBUG 依然被設置為False )。

注意  500錯誤頁面不會顯示任何有關當前使用者的資訊,因為發生伺服器錯誤時,Django不會通過回應發送任何上下文資訊。

3. 將修改推送到Heroku

現在需要提交對範本所做的修改,並將這些修改推送到Heroku

 

(ll_env)learning_log$ git add .

(ll_env)learning_log$ git commit -am "Added custom 404 and 500 error pages."

   3 files changed, 15 insertions(+), 10 deletions(-)

   create mode 100644 learning_log/templates/404.html

   create mode 100644 learning_log/templates/500.html

(ll_env)learning_log$ git push heroku master

  --snip--

  remote: Verifying deploy.... done.

  To https://git.heroku.com/learning-log.git

     2b34ca1..a64d8d3  master -> master

  (ll_env)learning_log$

 

 

 

 

 

 

 

 

處,我們執行了命令git add ,這是因為我們在專案中創建了一些新檔,因此需要讓Git跟蹤這些檔。然後,我們提交所做的修改(見),並將修改後的專案推送到Heroku(見

現在,錯誤頁面出現時,其樣式應該與網站的其他部分一致,這樣在發生錯誤時,使用者將不會感到突兀。

4. 使用方法get_object_or_404()

現在,如果使用者手工請求不存在的主題或條目,將導致500錯誤。Django嘗試渲染請求的頁面,但沒有足夠的資訊來完成這項任務,進而引發500錯誤。對於這種情形,將其視為404錯誤更合適,為此可使用Django快捷函數get_object_or_404() 。這個函數嘗試從資料庫獲取請求的物件,如果這個物件不存在,就引發404異常。我們在views.py中導入這個函數,並用它替換函數get() 

views.py

 

--snip--

from django.shortcuts import render, get_object_or_404

from django.http import HttpResponseRedirect, Http404

--snip--

@login_required

def topic(request, topic_id):

    """顯示單個主題及其所有的條目"""

    topic = get_object_or_404(Topic, id=topic_id)

    # 確定主題屬於當前使用者

    --snip--

 

 

 

 

 

 

 

 

現在,如果你請求不存在的主題(例如,使用URL http://localhost:8000/topics/999999/ ),將看到404錯誤頁面。為部署這裡所做的修改,再次提交,並將專案推送到Heroku

20.2.18 繼續開發

將專案學習筆記推送到伺服器後,你可能想進一步開發它或開發要部署的其他專案。更新項目的過程幾乎完全相同。

首先,你對本地專案做必要的修改。如果在修改過程中創建了新檔,使用命令git add . (千萬別忘記這個命令末尾的句點)將它們加入到Git倉庫中。如果有修改要求遷移資料庫,也需要執行這個命令,因為每個遷移都將生成新的遷移檔。

然後,使用命令git commit -am "commit message "將修改提交到倉庫,再使用命令git push heroku master 將修改推送到Heroku。如果你在本地遷移了資料庫,也需要遷移線上資料庫。為此,你可以使用一次性命令heroku run python manage.py migrate ,也可使用heroku run bash 打開一個遠端終端機會話,並在其中執行命令python manage.py migrate 。然後訪問線上項目,確認你期望看到的修改已生效。

在這個過程中很容易犯錯,因此看到錯誤時不要大驚小怪。如果代碼不能正確地工作,請重新審視所做的工作,嘗試找出其中的錯誤。如果找不出錯誤,或者不知道如何撤銷錯誤,請參閱附錄C中有關如何尋求幫助的建議。不要羞於去尋求幫助:每個學習開發專案的人都可能遇到過你面臨的問題,因此總有人樂意伸出援手。通過解決遇到的每個問題,可讓你的技能穩步提高,最終能夠開發可靠而有意義的專案,還能解決別人遇到的問題。

20.2.19 設置SECRET_KEY

Django根據settings.py中設置SECRET_KEY 的值來實現大量的安全協議。在這個項目中,我們提交到倉庫的設置檔包含設置SECRET_KEY 。對於一個練習項目而言,這足夠了,但對於生產網站,應更細緻地處理設置SECRET_KEY 。如果你創建的項目的用途很重要,務必研究如何更安全地處理設置SECRET_KEY 

20.2.20 將項目從Heroku刪除

一個不錯的練習是,使用同一個專案或一系列小專案執行部署過程多次,直到對部署過程瞭若指掌。然而,你需要知道如何刪除部署的專案。Heroku可能還限制了你可免費託管的項目數,另外,你也不希望讓自己的帳戶中塞滿大量的練習專案。

Heroku網站(https://heroku.com/ )登錄後,你將被重定向到一個頁面,其中列出了你託管的所有專案。按一下要刪除的專案,你將看到另一個頁面,其中顯示了有關這個專案的資訊。按一下連結Settings,再向下滾動,找到用於刪除專案的連結並按一下它。這種操作是不可撤銷的,因此Heroku讓你手工輸入要刪除的項目的名稱,以確認你確實要刪除它。

如果你喜歡在終端中工作,也可使用命令destroy 來刪除專案:

 

(ll_env)learning_log$ heroku apps:destroy --app appname

 

 

 

 

 

 

 

 

其中 appname 是要刪除的專案的名稱,可能類似於afternoon-meadow-2775 ,也可能類似於learning-log (如果你重命名了項目)。你將被要求再次輸入專案名,以確認你確實要刪除它。

注意  刪除Heroku上的專案對本地專案沒有任何影響。如果沒有人使用你部署的專案,就儘管去練習部署過程好了,在Heroku刪除專案再重新部署完全合情合理。

 

動手試一試

20-3 線上博客 :將你一直在開發的專案Blog部署到Heroku。確保將DEBUG 設置為False ,並修改設置ALLOWED_HOSTS ,讓部署相當安全。

20-4 在更多的情況下顯示404錯誤頁面 :在視圖函數new_entry() edit_entry() 中,也使用函數get_object_or_404() 。完成這些修改後進行測試:輸入類似於http://localhost:8000/new_entry/99999/URL,確認你能夠看到404錯誤頁面。

20-5 擴展學習筆記 :在學習筆記中添加一項功能,將修改推送到線上部署。嘗試做一項簡單的修改,如在主頁中對專案作更詳細的描述;再嘗試添加一項更高級的功能,如讓使用者能夠將主題設置為公開的。為此,需要在模型Topic 中添加一個名為public 的屬性(其預設值為False ),並在new_topic 頁面中添加一個表單元素,讓使用者能夠將私有主題改為公開的。然後,你需要遷移專案,並修改views.py,讓未登錄的用戶也可以看到所有公開的主題。將修改推送到Heroku後,別忘了遷移線上資料庫。

20.3 小結

在本章中,你學習了如何使用Bootstrap庫和應用程式django-bootstrap3賦予應用程式簡單而專業的外觀。使用Bootstrap意味著無論使用者使用哪種設備來訪問你的專案,你選擇的樣式都將實現幾乎相同的效果。

你學習了Bootstrap的範本,並使用範本Static top navbar賦予了學習筆記簡單的外觀。你學習了如何使用jumbotron來突出主頁中的消息,還學習了如何給網站的所有網頁設置一致的樣式。

在本章的最後一部分,你學習了如何將專案部署到Heroku的伺服器,讓任何人都能夠訪問它。你創建了一個Heroku帳戶,並安裝了一些幫助管理部署過程的工具。你使用Git將能夠正確運行的項目提交到一個倉庫,再將這個倉庫推送到Heroku的伺服器。最後,你將DEBUG 設置為False ,以確保線上伺服器上應用程式的安全。

至此,開發完了專案學習筆記後,你可以自己動手開發專案了。請先讓專案盡可能簡單,確定它能正確運行後,再添加複雜的功能。願你學習愉快,開發專案時有好運相伴!

0 留言:

發佈留言