在本篇文章中,我們將介紹如何使用 Django 發(fā)送電子郵件。我們將介紹如何配置 Django SMTP 連接,如何為你的電子郵件提供商設(shè)置應(yīng)用程序密碼,以及如何通過 Django shell 發(fā)送電子郵件。我們還將研究如何為你的 Django 應(yīng)用程序設(shè)置聯(lián)系表單,這將允許你的客戶與你聯(lián)系。
大多數(shù) Web 應(yīng)用程序使用電子郵件來管理關(guān)鍵操作,例如重置密碼、帳戶激活、接收客戶反饋、發(fā)送新聞通訊和營銷活動。這些任務(wù)中的大多數(shù)都需要像?SendGrid
?或?Mailgun
?這樣的專用服務(wù)。但是,如果你不希望你的網(wǎng)站獲得大量訪問者,你實(shí)際上可以通過你的個(gè)人電子郵件提供商完成很多工作。
了解 SMTP
SMTP(或簡單郵件傳輸協(xié)議)是一組用于確定電子郵件如何從發(fā)件人傳輸?shù)绞占说囊?guī)則。SMTP 服務(wù)器使用此協(xié)議來發(fā)送和中繼外發(fā)電子郵件。(請注意,其他協(xié)議管理電子郵件的接收方式。)
SMTP 服務(wù)器始終具有唯一的地址和用于發(fā)送消息的特定端口,在大多數(shù)情況下為587。我們將看到在使用 Django 發(fā)送電子郵件時(shí)端口是如何相關(guān)的。
由于我們將使用 Gmail,因此我們將使用的地址是?smtp.gmail.com
?,端口是 ?587
?。
現(xiàn)在讓我們看看如何使用 Django 發(fā)送電子郵件。
創(chuàng)建 Django 項(xiàng)目
每個(gè) Django 項(xiàng)目都應(yīng)該有一個(gè)虛擬環(huán)境,因?yàn)槲覀儾幌肱獊y項(xiàng)目依賴項(xiàng)。要?jiǎng)?chuàng)建一個(gè),請運(yùn)行以下命令:
python -m venv .venv
上面的命令創(chuàng)建了一個(gè)名為 的虛擬環(huán)境.venv。要激活此虛擬環(huán)境,您可以使用以下命令:
source .venv/bin/activate
由于 Django 是第三方包,你必須用 pip 安裝它:
pip install django
這將安裝最新版本的 Django,你可以使用pip freeze.
要?jiǎng)?chuàng)建 Django 項(xiàng)目,請調(diào)用命令行實(shí)用程序?django-admin
?:
django-admin startproject EmailProject
使用上面的命令,你正在創(chuàng)建一個(gè)名為 的 Django 項(xiàng)目?EmailProject
?,但你可以使用任何你想要的名稱創(chuàng)建該項(xiàng)目。
現(xiàn)在,進(jìn)入項(xiàng)目目錄并運(yùn)行服務(wù)器:
cd EmailProject
python manage.py runserver
運(yùn)行 Django 服務(wù)器后,在瀏覽器中訪問http://localhost:8000。你將看到一個(gè)自動生成的頁面,其中包含最新的 Django 發(fā)行說明。
修改設(shè)置
你需要在發(fā)送電子郵件之前修改設(shè)置文件,因此讓我們使用以下命令找到該文件tree:
注意:為簡單起見,我們將僅使用 UNIX(macOS 或 Linux)系統(tǒng)命令。
tree
該tree命令輸出目錄的文件結(jié)構(gòu)。在這種情況下,由于我們沒有給它一個(gè)特定的目錄路徑,如果我們在項(xiàng)目的根文件夾中,我們將得到類似于以下的內(nèi)容:
├── EmailProject
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
1 directory, 6 files
我們將在本教程中不斷修改的文件是?EmailProject
?文件夾中的?settings.py
? 。
?settings.py
?包含您需要的所有項(xiàng)目配置,并允許你設(shè)置自定義變量。正如 Django 文檔所說,“設(shè)置文件只是一個(gè)帶有模塊級變量的 Python 模塊”。
讓我們看一下使用 Django 發(fā)送電子郵件所需的設(shè)置。打開?EmailProject/settings.py
?文件并將以下設(shè)置粘貼到文件底部:
# EmailProject/settings.py
# Bottom of the file
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = ''
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
讓我們通過分析這些設(shè)置中的每一個(gè)來分解上面的代碼。
電子郵件后端
該?EMAIL_BACKEND
?設(shè)置聲明后端我們的Django項(xiàng)目將使用與SMTP服務(wù)器連接。
此變量指向?smtp.EmailBackend
?接收發(fā)送電子郵件所需的所有參數(shù)的類。我強(qiáng)烈建議你直接在Django 源代碼上查看類構(gòu)造函數(shù)。你可能會驚訝于這段代碼的可讀性。
注意:雖然這個(gè)類是默認(rèn)的??
EMAIL_BACKEND
??,但在 Django 設(shè)置中顯式被認(rèn)為是一個(gè)好習(xí)慣。
所有其他電子郵件設(shè)置將基于此?EmailBackend
? 類的構(gòu)造函數(shù)。
電子郵件主機(jī)
該?EMAIL_HOST
?設(shè)置指的是你將使用的 SMTP 服務(wù)器域。這取決于你的電子郵件提供商。下表列出了與三個(gè)常見提供商對應(yīng)的 SMTP 服務(wù)器主機(jī):
電子郵件提供商 | SMTP 服務(wù)器主機(jī) |
---|---|
Gmail | smtp.gmail.com |
Outlook/Hotmail | smtp-mail.outlook.com |
雅虎 | smtp.mail.yahoo.com |
我們暫時(shí)將此設(shè)置留空,因?yàn)槲覀兩院髮⑹褂?.env
?文件來避免硬編碼敏感密鑰或每個(gè)站點(diǎn)的配置。你永遠(yuǎn)不應(yīng)該將憑據(jù)直接設(shè)置到代碼中。
我們將使用?Django Environ
?來解決這個(gè)問題。
電子郵件端口
該?EMAIL_PORT
?設(shè)置必須設(shè)置為?587
?,因?yàn)樗谴蠖鄶?shù) SMTP 服務(wù)器的默認(rèn)端口。對于個(gè)人電子郵件提供商而言,情況仍然如此。
此端口與 TLS 加密一起使用,以確保電子郵件發(fā)送的安全性。
電子郵件使用 TLS
傳輸層安全(TLS) 是一種跨 Web 使用的安全協(xié)議,用于加密 Web 應(yīng)用程序 (Django) 和服務(wù)器 (SMTP 服務(wù)器) 之間的通信。
最初,我們將?EMAIL_USE_TLS
?變量設(shè)置為?True
?。這意味著 Django 將使用傳輸層安全連接到 SMTP 服務(wù)器并發(fā)送電子郵件。(對于個(gè)人電子郵件提供商,這是強(qiáng)制性的。)
電子郵件主機(jī)用戶
?EMAIL_HOST_USER
?設(shè)置是你的個(gè)人電子郵件地址?,F(xiàn)在將其留空,因?yàn)槲覀儗⑹褂盟?django-environ
?來設(shè)置所有這些憑據(jù)。
電子郵件主機(jī)密碼
?EMAIL_HOST_PASSWORD
?設(shè)置是你將從你的電子郵件帳戶中獲得的應(yīng)用密碼 - 我們將在本節(jié)之后立即執(zhí)行此過程。
同樣:將此設(shè)置留空,因?yàn)槲覀兩院髮⑹褂铆h(huán)境變量。
在 Gmail 中設(shè)置應(yīng)用密碼
要使用?EMAIL_HOST_PASSWORD
?設(shè)置,你需要激活安全性較低的應(yīng)用訪問權(quán)限,并從你的個(gè)人電子郵件地址獲得應(yīng)用密碼。
如果你不激活安全性較低的應(yīng)用程序訪問權(quán)限,你可能會得到一個(gè)?SMTPAuthenticationError
?,因?yàn)?Django 無法遵守 Google 安全協(xié)議。
你可以選擇使用普通密碼,但這比使用應(yīng)用密碼風(fēng)險(xiǎn)更大。我的建議是創(chuàng)建一個(gè)新的 Gmail 帳戶或使用“測試”電子郵件地址。
考慮到這一點(diǎn),你可以通過以下步驟獲取?Gmail
?應(yīng)用密碼。請注意,如果你使用的是現(xiàn)有帳戶并啟用了兩步驗(yàn)證,則可以跳過第 2 步和第 3 步:
- 創(chuàng)建或登錄 Gmail 帳戶
- 轉(zhuǎn)到myaccount.google.com/lesssecureapps并打開安全性較低的應(yīng)用程序選項(xiàng)。
- 啟用雙因素身份驗(yàn)證,因?yàn)樾枰@取應(yīng)用密碼。
- 現(xiàn)在你已啟用雙因素身份驗(yàn)證,是時(shí)候獲取應(yīng)用密碼了。為此,你可以轉(zhuǎn)到Google 帳戶的安全部分,向下滾動到登錄 Google 部分,然后點(diǎn)擊應(yīng)用密碼。
在被重定向到應(yīng)用程序密碼頁面之前,你需要重新提示您的密碼(帳戶密碼)。
進(jìn)入后,單擊?select app
?,你將為該應(yīng)用程序密碼選擇一個(gè)自定義名稱 - 例如“?Django Send Email
?” - 然后單擊?GENERATE
?。
將顯示一個(gè)新窗口,其中包含一個(gè) ?16
? 個(gè)字符的密碼。復(fù)制它,因?yàn)槲覀冃枰鼇砼渲梦覀兊?Django 項(xiàng)目。
使用 Django Environ 隱藏敏感鍵
即使你只是在開發(fā)中發(fā)送電子郵件,也不應(yīng)該將密碼直接寫入源代碼。當(dāng)使用版本控制系統(tǒng)和 GitHub 來托管你的項(xiàng)目時(shí),這一點(diǎn)變得更加重要。你不希望人們訪問你的數(shù)據(jù)。
讓我們看看如何通過使用?Django-environ
?來防止這種情況發(fā)生。
使用以下命令?.env
?在?EmailProject
?目錄(?settings.py
?文件所在的位置)內(nèi)創(chuàng)建一個(gè)文件:
cd EmailProject/
ls
settings.py # The settings file must be here
touch .env
現(xiàn)在,打開該?.env
?文件并輸入以下鍵值對:
EMAIL_HOST=smtp.gmail.com
EMAIL_HOST_USER=YourEmail@address
EMAIL_HOST_PASSWORD=YourAppPassword
RECIPIENT_ADDRESS=TheRecieverOfTheMails
分解此文件的內(nèi)容:
- ?
EMAIL_HOST
?:你的電子郵件提供商 SMTP 服務(wù)器地址。請參閱上面的電子郵件主機(jī)表以獲取快速指導(dǎo)。在本例中,我使用的?smtp.gmail.com
?是 Gmail SMTP 地址。 - ?
EMAIL_HOST_USER
?:你的電子郵件地址。 - ?
EMAIL_HOST_PASSWORD
?:你剛剛生成的應(yīng)用密碼。請記住,它不包含任何空格。 - ?
RECIPIENT_ADDRESS
?:你將收到郵件的電子郵件地址。這是我們稍后將創(chuàng)建的自定義設(shè)置,用于將所有電子郵件發(fā)送給同一收件人。
要使用這些環(huán)境變量,我們需要安裝?Django-environ
?:
pip install django-environ
注意:確保你的虛擬環(huán)境已激活。
現(xiàn)在,打開?settings.py
?位于?EmailProject
?目錄中的 并使用以下代碼:
# EmailProject/settings.py
# This should be at the start of the file
import environ
env = environ.Env()
environ.Env.read_env()
# Previous settings ...
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = env('EMAIL_HOST')
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = env('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD')
# Custom setting. To email
RECIPIENT_ADDRESS = env('RECIPIENT_ADDRESS')
首先,我們在?environ
?設(shè)置文件的頂部導(dǎo)入包。請記住,所有導(dǎo)入都應(yīng)在開頭。
然后我們創(chuàng)建一個(gè)?env
?變量,該變量將包含?.env
?.
?env('KEY')
?語句意味著我們正在查找該鍵的值。確保?.env
?在繼續(xù)之前設(shè)置了文件,因?yàn)槿绻?ImproperlyConfigured
?未設(shè)置某些環(huán)境變量,你將收到 Django錯(cuò)誤。
請注意,這?RECIPIENT_ADDRESS
?是一個(gè)自定義設(shè)置,我們將使用它來將電子郵件發(fā)送到我們可以訪問的地址。
如果你使用 Git 和 GitHub .env,請不要忘記在?.gitignore
?中包含該文件。你只需打開它并添加以下行即可完成此操作:
.env
1. 使用 Django Shell 發(fā)送電子郵件
最后,我們進(jìn)入了文章的精彩部分!是時(shí)候向 Django 發(fā)送你的第一封電子郵件了。
打開終端,激活虛擬環(huán)境,然后運(yùn)行:
python manage.py shell
這將創(chuàng)建一個(gè) shell,其中包含已為我們配置的所有 Django 設(shè)置。在那個(gè)全新的 shell 中,粘貼以下代碼:
>>> from django.core.mail import send_mail
>>> from django.conf import settings
>>> send_mail(
... subject='A cool subject',
... message='A stunning message',
... from_email=settings.EMAIL_HOST_USER,
... recipient_list=[settings.RECIPIENT_ADDRESS])
1
我們也可以在不指定參數(shù)的情況下制作單行:
>>> send_mail('A cool subject', 'A stunning message', settings.EMAIL_HOST_USER, [settings.RECIPIENT_ADDRESS])
1
讓我們分解上面的代碼:
- 我們導(dǎo)入 Django ?
send_mail
?函數(shù)。 - 然后我們導(dǎo)入settings包含所有全局設(shè)置和每個(gè)站點(diǎn)設(shè)置(settings.py文件內(nèi)的設(shè)置)的對象。
- 最后,我們將所有需要的參數(shù)傳遞給?
send_mail
?函數(shù)。此函數(shù)返回發(fā)送的電子郵件數(shù)量,在本例中為1。
請注意我們?nèi)绾问褂胹ettings對象來獲取?from_email
?(您用來發(fā)送電子郵件的電子郵件)和?recipient_list
?(??我們在?RECIPIENT_ADDRESS
?中定義的自定義設(shè)置?.env
?)。
現(xiàn)在,如果我檢查我的收件箱——當(dāng)我將?RECIPIENT_ADDRESS
?環(huán)境變量設(shè)置為我的電子郵件地址時(shí)——我將收到 Django 發(fā)送的消息。
2. 使用 Django 構(gòu)建自動聯(lián)系表單
在本節(jié)中,我們將使用 Django 表單和內(nèi)置?send_mail
?函數(shù)構(gòu)建一個(gè)自動聯(lián)系表單。此外,我們將?send()
?在聯(lián)系表單中創(chuàng)建一個(gè)自定義函數(shù) ,以便在視圖中更容易實(shí)現(xiàn)它。
讓我們從創(chuàng)建聯(lián)系人應(yīng)用程序開始。進(jìn)入項(xiàng)目根目錄——所在?manage.py的
?位置——并運(yùn)行:
python manage.py startapp contact
然后,將其安裝在文件?INSTALLED_APPS
?內(nèi)的變量中?EmailProject/settings.py
?:
# EmailProject/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
...
# Custom
'contact',
]
在推進(jìn)contact應(yīng)用程序之前,讓我們配置文件的?urlpatterns
?內(nèi)部?EmailProject/urls.py
?。為此,請導(dǎo)入?django.urls.include
?函數(shù)并在整個(gè)項(xiàng)目中包含聯(lián)系人 URL。別擔(dān)心;我們稍后將配置聯(lián)系人 URL:
# EmailProject/urls.py
from django.contrib import admin
from django.urls import path, include # New import
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('contact.urls')) # Include Contact URLs
]
聯(lián)系表
進(jìn)入contact應(yīng)用程序文件夾并創(chuàng)建一個(gè)?forms.py
?文件。在?forms.py
?文件中定義所有表單是一種很好的做法,但這不是強(qiáng)制性的。這就是 Django 默認(rèn)不包含這個(gè)文件的原因。
你可以使用以下命令創(chuàng)建表單文件:
cd ../contact/
# You were inside the EmailProject folder
touch forms.py
打開你剛剛創(chuàng)建的文件并進(jìn)行以下導(dǎo)入:
# contact/forms.py
from django import forms
from django.conf import settings
from django.core.mail import send_mail
Django表單模塊為我們提供了創(chuàng)建聯(lián)系表單所需的所有類和字段。我們再次導(dǎo)入?settings
?對象和?send_mail
?發(fā)送電子郵件的函數(shù)。
我們的聯(lián)系表單將包含多個(gè)字段并使用兩種自定義方法:?get_info()
?,用于格式化用戶提供的信息,以及?send()
?,將發(fā)送消息。
讓我們看看這在代碼中的實(shí)現(xiàn):
# contact/forms.py
class ContactForm(forms.Form):
name = forms.CharField(max_length=120)
email = forms.EmailField()
inquiry = forms.CharField(max_length=70)
message = forms.CharField(widget=forms.Textarea)
def get_info(self):
"""
Method that returns formatted information
:return: subject, msg
"""
# Cleaned data
cl_data = super().clean()
name = cl_data.get('name').strip()
from_email = cl_data.get('email')
subject = cl_data.get('inquiry')
msg = f'{name} with email {from_email} said:'
msg += f'\n"{subject}"\n\n'
msg += cl_data.get('message')
return subject, msg
def send(self):
subject, msg = self.get_info()
send_mail(
subject=subject,
message=msg,
from_email=settings.EMAIL_HOST_USER,
recipient_list=[settings.RECIPIENT_ADDRESS]
)
這是一個(gè)巨大的類,所以讓我們分解我們在每個(gè)部分中所做的事情。首先,我們定義了發(fā)送消息所需的四個(gè)字段:
- ?
name
?和?enquiry
?是表示聯(lián)系消息的名稱和原因的?CharFields
?。 - ?
email
?是一個(gè)?EmailField
?,代表試圖與您聯(lián)系的人的電子郵件。考慮到電子郵件不會由用戶的電子郵件地址發(fā)送,而是由您在 Django 項(xiàng)目中設(shè)置的發(fā)送電子郵件的電子郵件地址發(fā)送。 - ?
message
?是另一個(gè)?CharField
?例外,我們使用的是?Textarea
?小部件。這意味著,當(dāng)顯示表單時(shí),它將呈現(xiàn)一個(gè)?<textarea>
?標(biāo)簽而不是一個(gè)簡單的?<input>
?.
進(jìn)入自定義方法,我們只使用該?get_info
?方法來格式化用戶提供的信息并返回兩個(gè)變量:?subject
?,它只是?inquiry
?字段,以及?message
?,它將是 Django 發(fā)送的實(shí)際消息。
另一方面,該?send()
?方法僅從函數(shù)中獲取格式化信息?get_info
?并發(fā)送消息?send_mail
?。
盡管本節(jié)非常大,但你將看到我們?nèi)绾瓮ㄟ^將所有發(fā)送邏輯實(shí)現(xiàn)到?ContactForm
?自身來簡化聯(lián)系人視圖。
聯(lián)系人視圖
打開?contact/views.py
?文件并添加以下導(dǎo)入:
# contact/views.py
from django.views.generic import FormView, TemplateView
from .forms import ContactForm
from django.urls import reverse_lazy
如你所見,我們將使用Django 通用視圖,這在執(zhí)行簡單任務(wù)時(shí)為我們節(jié)省了大量時(shí)間——例如,在?FormView
?使用?TemplateView
?.
此外,我們正在導(dǎo)入?ContactForm
?我們在上一節(jié)中構(gòu)建的 以及在使用基于類的視圖時(shí)使用的?reverse_lazy
?函數(shù)。
繼續(xù)查看視圖,讓我們編寫?ContactView
?:
# contact/views.py
class ContactView(FormView):
template_name = 'contact/contact.html'
form_class = ContactForm
success_url = reverse_lazy('contact:success')
def form_valid(self, form):
# Calls the custom send method
form.send()
return super().form_valid(form)
如你所見,我們正在使用我們創(chuàng)建的構(gòu)建一個(gè)簡單的?FormView
??ContactForm
?。我們也在設(shè)置?template_name
?和?success_url
?。我們稍后將編寫 HTML 模板并設(shè)置 URL。
該形式有效的方法,讓我們用發(fā)送電子郵件?ContactForm.send()
?只有在形式的所有字段都是有效的方法。這意味著如果用戶輸入無效的輸入——例如未格式化的電子郵件地址——消息將不會被發(fā)送。
?form_valid
?在基于函數(shù)的視圖中,上述方法實(shí)現(xiàn)將等效于以下內(nèi)容:
# Previous function based contact_view ...
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
form.send()
return redirect('contact:success')
else:
form = ContactForm())
在本節(jié)結(jié)束時(shí),我們將編寫一個(gè)?ContactSucessView
?,它將向用戶顯示一條成功消息。由于我們已經(jīng)導(dǎo)入了?TemplateView
?類,我們只需要繼承它并定義?template_name
?屬性:
# contact/views.py
class ContactSuccessView(TemplateView):
template_name = 'contact/success.html'
聯(lián)系網(wǎng)址
是時(shí)候創(chuàng)建contact應(yīng)用程序的 URL 模式了。由于 ?Djangourls.py
?默認(rèn)不給我們文件,我們需要使用以下命令創(chuàng)建它(確保在?contactapp
?文件夾中):
pwd
# /path/to/project/EmailProject/contact
touch urls.py
打開該文件并設(shè)置?app_name
?和?urlpatterns
?變量:
from django.urls import path
from .views import ContactView, ContactSuccessView
app_name = 'contact'
urlpatterns = [
path('', ContactView.as_view(), name="contact"),
path('success/', ContactSuccessView.as_view(), name="success"),
]
我們使用路徑將路由及其對應(yīng)視圖包含到應(yīng)用程序的 URL 配置中。當(dāng)我們將app_name變量設(shè)置為 時(shí)'contact',這意味著應(yīng)用程序的 URL命名空間將如下所示:
contact:name_of_path
# For ContactView
contact:contact
# For ContactSuccessView
contact:success
注意:命名空間是我們在 Django 模板和視圖中動態(tài)調(diào)用的 URL。
你可以在官方文檔中了解有關(guān) Django URL 調(diào)度程序的更多信息。
編寫模板
Django 模板是動態(tài)顯示數(shù)據(jù)的首選方式,使用HTML和 Django 模板語言給我們的特殊標(biāo)簽。
對于這個(gè)特定的應(yīng)用程序,我們將使用三個(gè)模板:
- ?
base.html
?: 所有其他模板都將從它繼承。它將包含所有模板必須具有的所有 HTML 框架,以及指向 Bootstrap 的鏈接。 - ?
contact.html
?:顯示聯(lián)系表格。 - ?
success.html
?: 顯示成功消息。
讓我們從創(chuàng)建聯(lián)系人的應(yīng)用程序模板結(jié)構(gòu)開始(確保你在聯(lián)系人應(yīng)用程序文件夾中):
mkdir -p templates/contact/
cd templates/contact
touch base.html contact.html success.html
上面的命令創(chuàng)建了可重用 Django 應(yīng)用程序的典型模板結(jié)構(gòu)?appname/templates/appname
?——以及我之前提到的樹模板文件。
應(yīng)用程序文件結(jié)構(gòu)現(xiàn)在應(yīng)該如下所示:
.
├── admin.py
├── apps.py
├── forms.py
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── templates
│ └── contact
│ ├── base.html
│ ├── contact.html
│ └── success.html
├── tests.py
├── urls.py
└── views.py
讓我們進(jìn)入?base.html
?模板的內(nèi)容:
<!-- contact/templates/contact/base.html -->
<!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.0" />
<title>Django Email Send</title>
<link rel="stylesheet"
integrity="sha384-wEmeIV1mKuiNpC+IOBjI7aAzPcEZeedi5yW5f2yOq55WWLwNGmvvx4Um1vskeMj0" crossorigin="anonymous" />
</head>
<body>
{% block body %}
{% endblock %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-p34f1UUtsS3wqzfto5wAAmdvj+osOnFyQFpp4Ua3gs/ZVWx6oOypYoCJhGGScy+8" crossorigin="anonymous">
</script>
</body>
</html>
如你所見,它是包含Bootstrap 5鏈接的 HTML 文件的簡單框架。這允許我們在不使用 CSS 文件的情況下對我們的聯(lián)系人應(yīng)用程序進(jìn)行風(fēng)格化。
{% block name-of-block %}
?標(biāo)簽允許我們設(shè)置一個(gè)“子模板”將使用的占位符。使用此標(biāo)記使模板繼承成為一項(xiàng)簡單的任務(wù)。
在進(jìn)入表單之前,你需要安裝Django 脆皮表單包,它允許我們輕松地對它們進(jìn)行樣式化:
pip install django-crispy-forms
再一次,?crispy_forms
?是一個(gè) Django 應(yīng)用程序,我們需要將它包含在?INSTALLED_APPS
?列表中:
# config/settings.py
INSTALLED_APPS = [
...
# 3rd party apps
'crispy_forms',
# Custom apps
'contact',
]
# Indicates the frontend framework django crispy forms use
CRISPY_TEMPLATE_PACK = 'bootstrap4'
我們使用 Bootstrap 4 的模板包,因?yàn)?Bootstrap 表單類在第 4 版和第 5 版之間兼容(在撰寫本文時(shí))。
現(xiàn)在,讓我們處理?contact.html
?模板:
<!-- contact/templates/contact/contact.html -->
{% extends 'contact/base.html' %}
{% load crispy_forms_tags %}
{% block body %}
<div class="mx-auto my-4 text-center">
<h1>Contact Us</h1>
</div>
<div class="container">
<form action="" method="post">
{% csrf_token %}
{{ form | crispy }}
<button class="btn btn-success my-3" type="submit">Send message</button>
</form>
</div>
{% endblock %}
請注意我們?nèi)绾螖U(kuò)展基本模板并使用塊占位符。這就是 Django 模板語言如此高效的原因,因?yàn)樗屛覀児?jié)省了大量的 HTML 復(fù)制和粘貼。
談到表單,我們使用了方法"?post
?",這意味著我們ContactView將處理用戶提供的數(shù)據(jù),如果表單有效,我們將發(fā)送電子郵件。
{% csrf_token %}
?是由于安全原因,所有形式的強(qiáng)制性。Django 的文檔有一個(gè)關(guān)于CSRF 令牌的專用頁面以及在處理表單時(shí)使用它們的原因。
我們將使用crispy模板標(biāo)簽渲染表單,這就是為什么我們用?{% load crispy_forms_tags %}
?.
最后,讓我們編寫?success.html
?模板:
{% extends 'contact/base.html' %}
{% block body %}
<div class="mx-auto my-4 text-center">
<h1 class="fw-bolder text-success">We sent your message</h1>
<p class="my-5">You can send another in the <a href="{% url 'contact:contact' %}">contact page</a></p>
</div>
{% endblock %}
如你所見,這是一個(gè)簡單的成功公告,其中包含指向聯(lián)系表單的鏈接,以防用戶想要發(fā)送另一條消息。
讓我們再次運(yùn)行服務(wù)器并訪問http://localhost:8000(確保你已?.venv
?激活并且你在項(xiàng)目根文件夾中):
python manage.py runserver
下圖顯示了最終聯(lián)系表格的樣子。
這是成功消息的圖像。
這是收件箱中電子郵件的圖像。
總結(jié)
恭喜!你已經(jīng)學(xué)習(xí)了如何使用 Django 發(fā)送電子郵件以及如何構(gòu)建 Django 聯(lián)系表單。
使用 Django 發(fā)送電子郵件的方法有很多種。在本教程中,你已使用個(gè)人電子郵件地址完成此操作,但我希望你探索其他工具并將它們集成到你的項(xiàng)目中。
在本篇文章中,我們介紹了以下內(nèi)容:
- 如何設(shè)置 Django 設(shè)置以提供電子郵件
- 小項(xiàng)目中如何使用個(gè)人郵箱發(fā)送郵件
- 如何.env在 Django 項(xiàng)目中使用文件來使用敏感數(shù)據(jù)
- 如何構(gòu)建自動聯(lián)系表單