學習筆記專案實踐(python)

dirac(狄拉克)發表於2020-10-03

介紹:我們要編寫一個名為“學習筆記”的Web應用程式,讓使用者能夠記錄感興趣的主題,並在學習每個主題的過程中新增日誌條目。“學習筆記”的主頁對這個網站進行描述,並邀請使用者註冊或登入。使用者登入後,就可建立新主題、新增新條目以及閱讀既有的條目。
將使用Django的管理系統來輸入一些初始資料,再學習編寫檢視和模板,讓Django能夠為網站建立網頁。

一、Django入門

Django是一個Web框架 ——一套用於幫助開發互動式網站的工具。Django能夠響應網頁請求,還能讓你更輕鬆地讀寫資料庫、管理使用者等。

1.建立專案

1.1制定規範

1.2 建立虛擬環境

1.先建立目錄,命名為了learnning_log
2.切換目錄,建立虛擬環境

python -m venv ll_env

or

pip install --user virtualenv

3.啟用虛擬環境(win10)

ll_env\Scripts\activate

停止使用虛擬環境:deactivate
4.安裝Django

pip install Django

5.在Django中建立專案

django-admin.py startproject InstaBook .

6.檢視專案
python manage.py runserver

自動生成資料庫檔案db.sqlite2
在這裡插入圖片描述

開啟瀏覽器,並輸入URL:http://localhost:8000/

2.建立應用程式

Django專案 由一系列應用程式組成,它們協同工作,讓專案成為一個整體。

另外開啟一個終端,切換到manage.py

2.1定義資料模型

開啟檔案models.py,建立自己的模型,即使用者將要儲存的主題的模型

class Topic(models.Model):
    text = models.CharField(max_length=200)
    date_added = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        """返回模型的字串表示"""
        return self.text

2.2啟用模型

要使用模型,必須讓Django將應用程式包含到專案中。
開啟settings.py,將前面的應用程式新增到這個元組中
在這裡插入圖片描述
接下來,需要讓Django修改資料庫,使其能夠儲存與模型Topic 相關的資訊。為此,在終端視窗中執行下面的命令

python manage.py makemigrations learning_log

輸出表明Django建立了一個名為0001_initial.py的遷移檔案,這個檔案將在資料庫中為模型Topic 建立一個表。
應用這種遷移,讓Django替我們修改資料庫

python manage.py migrate

2.3 Django管理網站

為應用程式定義模型時,Django提供的管理網站(admin site)讓你能夠輕鬆地處理模型。網站的管理員可使用管理網站,但普通使用者不能使用。

  1. 建立超級使用者
 python manage.py createsuperuser
  1. 向管理網站註冊模型
    建立應用程式learning_logs 時,Django在models.py所在的目錄中建立了一個名為admin.py的檔案.
    為向管理網站註冊Topic
    在這裡插入圖片描述
    現在,使用超級使用者賬戶訪問管理網站:訪問http://localhost:8000/admin/
  2. 新增主題
    手動新增,add,方框輸入,save

2.4 定義模型Entry

需要為使用者可在學習筆記中新增的條目定義模型。每個條目都與特定主題相關聯,這種關係被稱為多對一關係,即多個條目可關聯到同一個主題。

models.py新增模型Entry 的程式碼

class Entry(models.Model):
    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):
            def __str__(self):
                if(len(self.text)<50):
                    return self.text[:50];
                else:
                    return self.text[:50] + "...";

2.5 遷移模型Entry

修改models.py,執行命令python manage.py makemigrations app_name ,再執行命令python manage.py migrate。
生成了一個新的遷移檔案——0002_entry.py

2.6向管理網站註冊Entry

修改admin.py
在這裡插入圖片描述
返回到http://localhost/admin/ ,你將看到learning_logs下列出了Entries。單擊Entries的Add連結,或者單擊Entries再選擇Add entry。你將看到一個下拉選單,讓你能夠選擇要為哪個主題建立條目,還有一個用於輸入條目的文字框。

2.7 Django shell

測試專案和排除其故障。
命令python manage.py shell 啟動一個Python直譯器。
可使用它來探索儲存在專案資料庫中的資料。

topics = Topic.objects.all()
for topic in topics:
	print(topic.id, topic)

t = Topic.objects.get(id=1)
t.text
t.date_added

3.建立網頁:學習筆記主頁

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

每個URL都被對映到特定的檢視 ——檢視函式獲取並處理網頁所需的資料。檢視函式通常呼叫一個模板,後者生成瀏覽器能夠理解的網頁。

3.1 對映URL

將這個基礎URL-http://localhost:8000/對映到“學習筆記”的主頁.
開啟專案主資料夾InstaBook中的檔案urls.py,新增程式碼
在這裡插入圖片描述
預設的urls.py包含在資料夾InstaBook中,現在我們需要在資料夾learning_logs中建立另一個urls.py檔案
在這裡插入圖片描述

3.2 編寫檢視

檢視函式接受請求中的資訊,準備好生成網頁所需的資料,再將這些資料傳送給瀏覽器——這通常是使用定義了網頁是什麼樣的模板實現的。
learning_logs中的檔案views.py是執行命令python manage.py startapp 時自動生成的。新增程式碼

from django.shortcuts import render

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

3.3 編寫模板

在資料夾learning_logs中新建一個資料夾,並將其命名為templates。在資料夾templates中,再新建一個資料夾,並將其命名為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>

4.建立其他網頁

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

4.1模板繼承

  1. 父模板
    首先來建立一個名為base.html的模板,並將其儲存在index.html所在的目錄中。這個檔案包含所有頁面都有的元素;其他的模板都繼承base.html。
<p>
<a href="{% url'learning_logs:index' %}">Learning Log</a>
</p>

{% block content %}{% endblock content %}
  1. 子模板
    現在需要重新編寫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%}

4.2顯示所有主題的頁面

  1. URL模式
    修改learning_logs/urls.py

在這裡插入圖片描述
2. 檢視
在views.py中新增程式碼
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 %}

修改父模板,使其包含到顯示所有主題的頁面的連結

在這裡插入圖片描述
在這裡插入圖片描述

4.3 顯示特定主題的頁面

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

  1. URL模式
    顯示特定主題的頁面的URL模式將使用主題的id 屬性來指出請求的是哪個主題。
    在這裡插入圖片描述
    在這裡插入圖片描述

  2. 檢視
    函式topic() 需要從資料庫中獲取指定的主題以及與之相關聯的所有條目
    在這裡插入圖片描述

  3. 模板
    這個模板需要顯示主題的名稱和條目的內容;如果當前主題不包含任何條目,我們還需向使用者指出這一點

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

  {% block content %}

  <p>Topic: {{ topic }}</p>

    <p>Entries:</p>
   <ul>
   {% for entry in entries %}
      <li>
	   <%在Django模板中,豎線(| )表示模板過濾器%>
       <p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
	   <%過濾器linebreaks將包含換行符的長條目轉換為瀏覽器能夠理解的格式%>
        <p>{{ entry.text|linebreaks }}</p>
      </li>
   {% empty %}
      <li>
        There are no entries for this topic yet.
      </li>
    {% endfor %}
    </ul>

  {% endblock content %}
  1. 將顯示所有主題的頁面中的每個主題都設定為連結
    在這裡插入圖片描述
    效果
    在這裡插入圖片描述

二、使用者賬號

將建立對使用者友好而直觀的網頁,讓使用者無需通過管理網站就能新增新的主題和條目,以及編輯既有的條目。我們還將新增一個使用者註冊系統,讓使用者能夠建立賬戶和自己的學習筆記。

在本章中,你將建立一些表單,讓使用者能夠新增主題和條目,以及編輯既有的條目。學習Django如何防範對基於表單的網頁發起的常見攻擊,所以無需花太多時間考慮確保應用程式安全的問題。

然後,實現一個使用者身份驗證系統。你將建立一個註冊頁面,供使用者建立賬戶,並讓有些頁面只能供已登入的使用者訪問。接下來,我們將修改一些檢視函式,使得使用者只能看到自己的資料。你將學習如何確保使用者資料的安全

1.讓使用者能夠輸入資料

使用Django的表單建立工具來建立讓使用者能夠輸入資料的頁面。

1.1 新增新主題

建立基於表單的頁面的方法幾乎與前面建立網頁一樣,一個主要差別是,需要匯入包含表單的模組forms.py。

  1. 用於新增主題的表單
    讓使用者輸入並提交資訊的頁面都是表單,在Django中,建立表單的最簡單方式是使用ModelForm,建立一個名為forms.py的檔案,將其儲存到models.py所在的目錄中
from django import forms

from .models import Topic
class TopicForm(forms.ModelForm):
    class Meta:
        model = Topic
        # 該表單只包含欄位text
        fields = ['text']
        # Django不要為欄位text 生成標籤。
        labels = {'text': ''}
  1. URL模式new_topic
    這個新網頁的URL應簡短而具有描述性,因此當使用者要新增新主題時,我們將切換到http://localhost:8000/new_topic/。
    將其新增到learning_logs/urls.py
    在這裡插入圖片描述
  2. 檢視函式new_topic()
    函式new_topic() 需要處理兩種情形:剛進入new_topic 網頁(在這種情況下,它應顯示一個空表單);對提交的表單資料進行處理,並將使用者重定向到網頁topics
    在這裡插入圖片描述
  3. 模板new_topic
    建立新模板new_topic.html,用於顯示我們剛建立的表單
{% extends "learning_logs/base.html" %}

  {% block content %}
    <p>Add a new topic:</p>

   <form action="{% url 'learning_logs:new_topic' %}" method='post'>
   <!-- Django使用模板標籤{% csrf_token %} 來防止攻擊者利用表單來獲得對伺服器未經授權的訪問(這種攻擊被稱為跨站請求偽造 )。-->
     {% csrf_token %}
	 <!--顯示錶單,讓Django自動建立顯示錶單所需的全部欄位。修飾符as_p 讓Django以段落格式渲染所有表單元素-->
     {{ form.as_p }}
     <button name="submit">add topic</button>
    </form>

  {% endblock content %}
  1. 連結到頁面new_topic
    在頁面topics 中新增一個到頁面new_topic 的連結:

1.2 新增新條目

在forms.py中再新增一個類

  1. 用於新增新條目的表單
    建立一個與模型Entry 相關聯的表單
    在這裡插入圖片描述
  2. URL模式new_entry
    learning_logs/urls.py中新增程式碼
    在這裡插入圖片描述
  3. 檢視函式new_entry()
    view.py
from django.urls import reverse
from .forms import TopicForm, EntryForm
def new_entry(request, topic_id):
    """在特定的主題中新增新條目"""
    topic = Topic.objects.get(id=topic_id)

    if request.method != 'POST':
          # 未提交資料,建立一個空表單
        form = EntryForm()
    else:
        # POST提交的資料,對資料進行處理
        form = EntryForm(data=request.POST)
        if form.is_valid():
            new_entry = form.save(commit=False)
            new_entry.topic = topic
            new_entry.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',
                                          args=[topic_id]))

    context = {'topic': topic, 'form': form}
    return render(request, 'learning_logs/new_entry.html', context)

  1. 模板new_entry
    類似於模板new_topic
{% extends "learning_logs/base.html" %}

  {% block content %}
   <p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>
	<p>Add a new entry:</p>
   <form action="{% url 'learning_logs:new_entry' topic.id %}" method='post'>
   <!-- Django使用模板標籤{% csrf_token %} 來防止攻擊者利用表單來獲得對伺服器未經授權的訪問(這種攻擊被稱為跨站請求偽造 )。-->
     {% csrf_token %}
	 <!--顯示錶單,讓Django自動建立顯示錶單所需的全部欄位。修飾符as_p 讓Django以段落格式渲染所有表單元素-->
     {{ form.as_p }}
     <button name="submit">add entry</button>
    </form>

  {% endblock content %}
  1. 連結到頁面new_entry
    加到頁面new_entry 的連結
    topic.html
    在這裡插入圖片描述

1.3 編輯條目

  1. URL模式edit_entry
    在這裡插入圖片描述
  2. 檢視函式edit_entry()
def edit_entry(request, entry_id):
    """編輯既有條目"""
    entry = Entry.objects.get(id=entry_id)
    topic = entry.topic

    if request.method != 'POST':
        # 初次請求,使用當前條目填充表單
        form = EntryForm(instance=entry)
    else:
        # POST提交的資料,對資料進行處理
        form = EntryForm(instance=entry, data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic.id]))

    context = {'entry': entry, 'topic': topic, 'form': form}
    return render(request, 'learning_logs/edit_entry.html', context)
  1. 模板edit_entry
    與模板new_entry.html類似
{% extends "learning_logs/base.html" %}

  {% block content %}
   <p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>
	<p>Edit entry:</p>
   <form action="{% url 'learning_logs:edit_entry' entry.id %}" method='post'>
   <!-- Django使用模板標籤{% csrf_token %} 來防止攻擊者利用表單來獲得對伺服器未經授權的訪問(這種攻擊被稱為跨站請求偽造 )。-->
     {% csrf_token %}
	 <!--顯示錶單,讓Django自動建立顯示錶單所需的全部欄位。修飾符as_p 讓Django以段落格式渲染所有表單元素-->
     {{ form.as_p }}
     <button name="submit">save changes</button>
    </form>

  {% endblock content %}
  1. 連結到頁面edit_entry
    在這裡插入圖片描述

2.建立使用者賬戶

建立一個使用者註冊和身份驗證系統,讓使用者能夠註冊賬戶,進而登入和登出。建立一個新的應用程式,其中包含與處理使用者賬戶相關的所有功能。我們還將對模型Topic 稍做修改,讓每個主題都歸屬於特定使用者。
命令startapp 來建立一個名為users 的應用程式:

python manage.py startapp users
  1. 將應用程式users 新增到settings.py中

在這裡插入圖片描述
2. 包含應用程式users 的URL
修改專案根目錄中的urls.py,使其包含我們將為應用程式users 定義的URL
在這裡插入圖片描述

2.2 登入頁面

在目錄InstaBook/users/中,新建一個名為urls.py的檔案,並在其中新增如下程式碼

#從 django-1.11開始,基於函式的登入,登出等檢視已被重寫為基於類的檢視: LoginView 和 LogoutView類
from django.conf.urls import url
#from django.contrib.auth.views import login
from django.contrib.auth.views import LoginView
from . import views

urlpatterns = [
    # 登入頁面
    #url(r'^login/$', login, {'template_name': 'users/login.html'},name='login'),
    url(r'^login/$',LoginView.as_view(template_name='users/login.html'),name='login'),

]
app_name ='users'
  1. 模板login.html
    在目錄InstaBook/users/中,建立一個名為templates的目錄,並在其中建立一個名為users的目錄
<!--注意,一個應用程式中的模板可繼承另一個應用程式中的模板。-->
{% extends "learning_logs/base.html" %}

  {% block content %}

   {% if form.errors %}
    <p>Your username and password didn't match. Please try again.</p>
    {% endif %}

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

   <button name="submit">log in</button>
   <!--包含了一個隱藏的表單元素——'next' ,其中的實參value 告訴Django在使用者成功登入後將其重定向到什麼地方——在這裡是主頁。-->
   <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
    </form>

  {% endblock content %}
  1. 連結到登入頁面
    下面在base.html中新增到登入頁面的連結,讓所有頁面都包含它。使用者已登入時,我們不想顯示這個連結,因此將它巢狀在一個{% if %} 標籤中
    在這裡插入圖片描述
  2. 使用登入頁面
    在這裡插入圖片描述

在這裡插入圖片描述

2.3登出

讓使用者只需單擊一個連結就能登出並返回到主頁。為此,我們將為登出連結定義一個URL模式,編寫一個檢視函式,並在base.html中新增一個登出連結。

  1. 登出URL
  2. 檢視函式logout_view()
    開啟users/views.py,並輸入下面的程式碼
from django.shortcuts import render

# Create your views here.
from django.http import HttpResponseRedirect
from django.urls import reverse
#from django.core.urlresolvers import reverse
from django.contrib.auth import logout

def logout_view(request):
    """登出使用者"""
    logout(request)
    return HttpResponseRedirect(reverse('learning_logs:index'))
  1. 連結到登出檢視
    在base.html中新增這種連結
    在這裡插入圖片描述

2.4 註冊頁面

建立一個讓新使用者能夠註冊的頁面。我們將使用Django提供的表單UserCreationForm

  1. 註冊頁面的URL模式
    在users/urls.py中
    在這裡插入圖片描述
  2. 檢視函式register()
    在註冊頁面首次被請求時,檢視函式register() 需要顯示一個空的登錄檔單,並在使用者提交填寫好的登錄檔單時對其進行處理。如果註冊成功,這個函式還需讓使用者自動登入。
    在users/views.py中新增如下
  3. 註冊模板
    與登入頁面的模板類似,儲存到login.html所在的目錄中:
{% extends "learning_logs/base.html" %}

{% block content %}

  <form method="post" action="{% url 'users:register' %}">
    {% csrf_token %}
    {{ form.as_p }}

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

{% endblock content %}
  1. 連結到註冊頁面

使用者沒有登入時顯示到註冊頁面的連結:
base.html
在這裡插入圖片描述

3.讓使用者擁有自己的資料

建一個系統,確定各項資料所屬的使用者,再限制對頁面的訪問,讓使用者只能使用自己的資料
修改模型Topic ,讓每個主題都歸屬於特定使用者。這也將影響條目,因為每個條目都屬於特定的主題。

3.1 使用@login_required 限制訪問

只允許已登入的使用者請求topics 頁面。為此,在learning_logs/views.py中新增如下程式碼:
在這裡插入圖片描述
settings.py
在這裡插入圖片描述
2. 全面限制對專案“學習筆記”的訪問
learning_logs/views.py中,對除index() 外的每個檢視都應用了裝飾器@login_required :
如果你在未登入的情況下嘗試訪問這些頁面,將被重定向到登入頁面。另外,你還不能單擊到new_topic 等頁面的連結。但如果你輸入URL http://localhost:8000/new_topic/,將重定向到登入頁面。對於所有與私有使用者資料相關的URL,都應限制對它們的訪問。

3.2 將資料關聯到使用者

修改模型Topic ,在其中新增一個關聯到使用者的外來鍵。這樣做後,我們必須對資料庫進行遷移。最後,我們必須對有些檢視進行修改,使其只顯示與當前登入的使用者相關聯的資料。

  1. 修改模型Topic
    models.py
    在這裡插入圖片描述
    在Topic 中新增了欄位owner ,它建立到模型User 的外來鍵關係。
  2. 確定當前有哪些使用者
    我們遷移資料庫時,Django將對資料庫進行修改,使其能夠儲存主題和使用者之間的關聯。為執行遷移,Django需要知道該將各個既有主題關聯到哪個使用者。最簡單的辦法是,將既有主題都關聯到同一個使用者,如超級使用者。為此,我們需要知道該使用者的ID。
python manage.py shell

啟動一個Django shell會話,並執行如下命令:

from django.contrib.auth.models import User
User.objects.all()
for user in User.objects.all():
	print(user.username, user.id)
  1. 遷移資料庫
    我們首先執行了命令makemigrations 。在輸出中,Django指出我們試圖給既有模型Topic 新增一個必不可少(不可為空)的欄位,而該欄位沒有預設值。Django提供了兩種選擇:要麼現在提供預設值,要麼退出並在models.py中新增預設值。處選擇了第一個選項,因此Django讓我們輸入預設值為將所有既有主題都關聯到管理使用者,輸入了使用者ID值1。。接下來,Django使用這個值來遷移資料庫,並生成了遷移檔案0003_topic_owner.py,它在模型Topic 中添欄位owner 。
    在這裡插入圖片描述

3.3 只允許使用者訪問自己的主題

不管你以哪個使用者的身份登入,都能夠看到所有的主題。我們來改變這種情況,只向使用者顯示屬於自己的主題。

在views.py中,對函式topics() 做如下修改

3.4 保護使用者的主題
沒有限制對顯示單個主題的頁面的訪問,因此任何已登入的使用者都可輸入類似於http://localhost:8000/topics/1/的URL,來訪問顯示相應主題的頁面。在檢視函式topic() 獲取請求的條目前執行檢查:
在這裡插入圖片描述

3.5保護頁面edit_entry

views.py,edit_entry方法新增如下程式碼

if topic.owner != request.user:
        raise Http404

3.6將新主題關聯到當前使用者

用於新增新主題的頁面存在問題,因此它沒有將新主題關聯到特定使用者。
views.py


測試後發現點選topic報錯:
OperationalError
no such column: learning_logs_topic.owner_id
搜尋資料如下解決
1.對models.py進行更改
在這裡插入圖片描述

2.建立資料庫遷移python manage.py makemigration learning_logs
3.執行遷移 python manage.py migrate恢復正常

三、設定應用程式的樣式並對其進行部署

1.1 應用程式django-bootstrap3

下載必要的Bootstrap檔案,專案的模板中使用樣式設定指令。
安裝django-bootstrap3,虛擬環境中執行pip install django-bootstrap3

在settings.py的INSTALLED_APPS 中新增如下程式碼
在這裡插入圖片描述
新建一個用於指定其他開發人員開發的應用程式的片段,將其命名為“第三方應用程式”,並在其中新增’bootstrap3’
在這裡插入圖片描述

1.2 使用Bootstrap來設定專案“學習筆記”的樣式

要檢視Bootstrap提供的模板,可訪問http://getbootstrap.com/.
使用模板Static top navbar,它提供了簡單的頂部導航條、頁面標題和用於放置頁面內容的容器。

1.3 修改base.html

  1. 定義HTML頭部
  2. 定義導航欄

1.4使用jumbotron設定主頁的樣式

1.5 設定登入頁面的樣式

1.6 設定new_topic 頁面的樣式

1.7 設定topics頁面的樣式

1.8 設定topic頁面中條目的樣式

2.部署“學習筆記”

使用Heroku,這是一個基於Web的平臺,能夠管理Web應用程式的部署。

2.1建立Heroku賬戶

https://heroku.com/

2.2安裝Heroku Toolbelt

https://toolbelt.heroku.com/

2.3 逐個安裝必要的包

pip install dj-database-url
pip install dj-static
pip install static3
pip install gunicorn

2.4建立包含包列表的檔案requirements.txt

開啟檔案requirements.txt,並新增程式碼行psycopg2>=2.6.1 。這將安裝2.6.1版的psycopg2

2.5 指定Python版本

新建一個名為runtime.txt的檔案,並在其中輸入自己電腦的python版本(python --version可檢視版本)。
在這裡插入圖片描述

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

在settings.py末尾新增一個片段,在其中指定一些Heroku環境設定:
在這裡插入圖片描述

2.7 建立啟動程式的Procfile

Procfile告訴Heroku啟動哪些程式,以便能夠正確地提供專案提供的服務。這個檔案只包含一行,將其命名為Procfile(其中的P為大寫),不指定副檔名,並儲存到manage.py所在的目錄中。
Prociflie內容如下:web: gunicorn learning_log.wsgi --log-file -
這行程式碼讓Heroku將gunicorn用作伺服器,並使用learning_log/wsgi.py中的設定來啟動應用程式。標誌log-file 告訴Heroku應將哪些型別的事件寫入日誌。

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

修改wsgi.py,因為Heroku需要的設定與我們一直在使用的設定稍有不同:
在這裡插入圖片描述

2.9建立用於儲存靜態檔案的目錄

新建一個名為static的資料夾,這個資料夾的路徑為InstaBook/InstaBook/static/。我們還需在這個資料夾中建立一個佔位檔案,因為專案被推送到Heroku時,它將不會包含原來為空的資料夾。在目錄static/中,建立一個名為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/.
#YOUARE122

使用Git跟蹤專案檔案

安裝並配置git後,在manage.py所在的資料夾中建立一個名為.gitignore。在這個檔案中輸入如下內容:

ll_env/
__pycache__/
*.sqlite3

讓Git忽略目錄llenv,
在manage.py所在的資料夾中建立一個名為.gitignore的檔案

新增專案
為“學習筆記”初始化一個Git倉庫,將所有必要的檔案都加入到這個倉庫中,並提交專案的初始狀態

git init
git add .
git commit -am "Ready for deployment to heroku."
git status

推送到Heroku,加-i引數避免開啟瀏覽器登入
heroku login -i
heroku create
git push heroku master(出錯可參照https://stackoverflow.com/questions/36665889/collectstatic-error-while-deploying-django-app-to-heroku解決:heroku config:set DISABLE_COLLECTSTATIC=1)
heroku ps
heroku open
下一步在Heroku上建立資料庫
heroku run python manage.py migrate
改進Heroku部署
1.在Heroku上建立超級使用者
heroku run bash
python manage.py createsuperuser
exit
2.在Heroku上建立對使用者友好的URL
heroku apps:rename name( Name must start with a letter, end with a letter or digit and can only contain lowercase
letters, digits, and dashes.)
3. 確保專案的安全
在這裡插入圖片描述

4.提交併推送修改
git commit -am “”
git status
git push heroku master
成功:
在這裡插入圖片描述

總結
執行失敗兩種原因:
1.伺服器沒啟動成功,檢視日誌heroku logs --tail發現專案名字錯誤,後來發現procfile裡專案名字寫錯,修改後成功
2.遇到錯誤程式碼400,setting.py的ALLOWED_HOSTS變數設定錯誤
其他:
1.註冊heroku較為麻煩,需要vpn,且下載非常慢。
2.參照教程程式碼一定要仔細,runtime.txt的python版本錯誤大寫,而伺服器區分大小寫,導致部署到伺服器失敗
參考:本專案參照了《python程式設計:從入門到實踐》

相關文章