第一章:Django 簡介
1.1 什么是 Django?
Django 是一個高級的 Python Web 框架,旨在讓 Web 開發變得更加快速和簡便。它鼓勵遵循“不要重復自己”(DRY,Don’t Repeat Yourself)的原則,并提供了一套完善的工具和庫來快速構建 Web 應用。Django 提供了很多內置的功能,包括:
- ORM(Object-Relational Mapping):簡化數據庫操作。
- 模板引擎:用來生成 HTML 頁面。
- 自動化管理界面:Django 自動生成一個管理后臺界面。
- 路由系統:URL 路由匹配。
- 安全性:防止常見的 Web 安全問題(如 SQL 注入、XSS 攻擊等)。
1.2 Django 的開發哲學
Django 強調“快速開發”和“可重用性”。它內置了很多功能,幫助開發者少寫代碼,同時保持代碼的清晰和可維護性。Django 項目結構清晰,規范性強,適合團隊開發。
第二章:Django 項目結構
2.1 創建一個 Django 項目
Django 的項目是一個包含了多個應用(App)的結構,每個應用都是一個相對獨立的模塊,通常代表一個功能或領域。你可以通過以下命令來創建一個新的 Django 項目:
django-admin startproject myproject
執行后,會在當前目錄下生成一個名為 myproject
的文件夾,里面包含一些默認的文件和目錄:
myproject/manage.py # 用于管理項目的命令行工具myproject/__init__.py # 標識這個目錄是一個 Python 包settings.py # 項目的配置文件urls.py # 項目的 URL 路由配置wsgi.py # 用于部署應用的 WSGI 配置
settings.py
是項目的核心配置文件。urls.py
用來定義項目級別的路由。wsgi.py
是部署用的文件,幫助將你的應用與服務器連接。
2.2 創建 Django 應用
在 Django 中,一個項目包含多個應用,每個應用是一個相對獨立的功能模塊。你可以通過以下命令來創建一個新的應用:
python manage.py startapp myapp
這將在項目目錄下創建一個新的應用,目錄結構大概如下:
myapp/__init__.pyadmin.py # 管理后臺配置apps.py # 應用配置models.py # 數據庫模型tests.py # 測試文件views.py # 視圖函數migrations/ # 數據庫遷移文件
2.3 項目和應用之間的關系
- 項目(Project): 一個 Django 項目是一個整體,包含了多個應用、配置文件以及數據庫等內容。
- 應用(App): 每個應用都是一個獨立的模塊,通常實現項目中的某個功能。
第三章:Django 的開發規范
3.1 遵循 Django 的項目結構
在 Django 中,項目和應用的結構是非常重要的。雖然你可以按照自己的需求調整項目和應用的組織方式,但通常建議保持 Django 的默認結構,這樣會更容易與其他開發者協作,并且方便日后的維護。
3.2 遵循 Python 的 PEP 8
Django 是用 Python 編寫的,所以在編寫 Django 代碼時,遵循 Python 的編碼規范(PEP 8)非常重要。PEP 8 是 Python 官方的編碼風格指南,涵蓋了代碼縮進、命名約定、空格的使用等方面。
- 類名使用駝峰式命名法(如
MyModel
)。 - 變量名和函數名使用小寫字母加下劃線命名法(如
get_user_profile
)。 - 代碼縮進使用 4 個空格。
3.3 遵循 Django 的約定
Django 提供了一些約定,遵循這些約定可以讓你寫出更簡潔、規范的代碼。比如:
- 模型命名:模型類的名稱應該采用單數形式,比如
Book
(表示一本書),而不是Books
。 - 視圖命名:視圖函數一般應該使用動詞短語,表示動作,比如
create_article
或view_article
。
3.4 使用 Django 提供的功能
Django 提供了許多開箱即用的功能,盡量不要重新發明輪子。例如,Django 已經實現了身份認證、權限控制、表單處理等常用功能,盡量使用它們而不是從頭開始編寫。
第四章:Django 的 URL 路由
4.1 URL 路由基礎
Django 的 URL 路由系統將 URL 與視圖函數綁定。你需要在 urls.py
文件中定義 URL 模式(patterns),并將它們映射到視圖函數。
示例:
# myproject/urls.py
from django.contrib import admin
from django.urls import path
from myapp import viewsurlpatterns = [path('admin/', admin.site.urls),path('hello/', views.hello_world),
]
在這個例子中,當訪問 /hello/
時,Django 會調用 views.hello_world
這個視圖函數。
4.2 動態 URL 參數
你還可以在 URL 中定義動態參數,并將其傳遞給視圖函數。例如,下面的路由會捕捉 URL 中的 id
參數,并傳遞給視圖:
# myproject/urls.py
urlpatterns = [path('article/<int:id>/', views.article_detail),
]
視圖函數接收該參數:
# myapp/views.py
from django.http import HttpResponsedef article_detail(request, id):return HttpResponse(f"Article ID is {id}")
好的,我們接著往下講解,深入一些 Django 的開發要點和常見的功能模塊。
第五章:Django 模型(Models)
5.1 什么是模型(Model)?
在 Django 中,模型是用來定義數據結構的類,通常與數據庫中的表一一對應。通過模型,你可以方便地定義、查詢和操作數據庫中的數據。Django 提供了一個 ORM(對象關系映射)系統,使得你可以用 Python 代碼來代替 SQL 查詢,簡化了數據庫操作。
5.2 創建模型
一個模型是繼承自 django.db.models.Model
的類。每個模型的屬性對應數據庫表中的字段。
例如,定義一個 Book
模型來表示書籍:
# myapp/models.py
from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=100)author = models.CharField(max_length=100)published_date = models.DateField()isbn = models.CharField(max_length=13)pages = models.IntegerField()def __str__(self):return self.title
這里的 Book
類有幾個字段:
CharField
:用于存儲字符數據,通常用于短文本。DateField
:用于存儲日期。IntegerField
:用于存儲整數。
5.3 創建和應用數據庫遷移
在創建或修改模型后,需要執行遷移(migration),這是 Django 管理數據庫的方式。
-
生成遷移文件:
python manage.py makemigrations
-
應用遷移:
python manage.py migrate
這兩個命令會同步數據庫的結構,使其與模型保持一致。
5.4 查詢數據庫
Django 提供了一個強大的查詢 API,允許你以 Python 的方式進行數據庫操作。
-
查詢所有書籍:
books = Book.objects.all()
-
過濾書籍:
books_by_author = Book.objects.filter(author='J.K. Rowling')
-
獲取單本書籍:
book = Book.objects.get(id=1)
-
添加新書籍:
new_book = Book(title="New Book", author="Author Name", published_date="2025-04-18", isbn="1234567890123", pages=300) new_book.save()
-
更新書籍信息:
book = Book.objects.get(id=1) book.title = "Updated Title" book.save()
-
刪除書籍:
book = Book.objects.get(id=1) book.delete()
5.5 模型的高級功能
- 字段選項:每個模型字段都有一些選項來控制字段的行為,比如
null=True
、blank=True
、default=value
等。 - 關系字段:Django 支持模型之間的關系,例如一對多、多對多關系等。
例如,一對多關系:
class Author(models.Model):name = models.CharField(max_length=100)class Book(models.Model):title = models.CharField(max_length=100)author = models.ForeignKey(Author, on_delete=models.CASCADE)
第六章:Django 視圖(Views)
6.1 什么是視圖?
視圖是處理 HTTP 請求并返回 HTTP 響應的函數或類。Django 支持兩種類型的視圖:函數視圖和類視圖。
6.2 函數視圖
函數視圖是最簡單的視圖形式,它是一個普通的 Python 函數,接收一個 request
參數并返回一個 HttpResponse
對象。
例如,定義一個簡單的視圖返回歡迎消息:
# myapp/views.py
from django.http import HttpResponsedef welcome(request):return HttpResponse("Welcome to Django!")
6.3 類視圖
類視圖是基于 Python 類的視圖,它使得視圖邏輯更加結構化和可重用。Django 提供了許多內置的類視圖,簡化了常見任務(如顯示列表、顯示單個對象等)。
例如,定義一個基于類的視圖來顯示書籍的列表:
# myapp/views.py
from django.views import View
from django.http import HttpResponse
from .models import Bookclass BookListView(View):def get(self, request):books = Book.objects.all()books_list = "\n".join([book.title for book in books])return HttpResponse(books_list)
6.4 使用視圖函數和類視圖的選擇
- 函數視圖適合簡單的場景和快速的開發。
- 類視圖適合處理復雜的請求邏輯,并且可以利用 Django 提供的通用視圖(如
ListView
、DetailView
)來加速開發。
第七章:Django 模板(Templates)
7.1 什么是模板?
模板用于呈現動態生成的 HTML 內容。Django 使用模板引擎來將數據渲染到 HTML 頁面中,分離了應用的邏輯和顯示內容。模板通常包含占位符,這些占位符在視圖中會被實際的數據替代。
7.2 渲染模板
要在視圖中使用模板,你需要使用 Django 的 render
函數來渲染模板并返回響應。
# myapp/views.py
from django.shortcuts import render
from .models import Bookdef book_list(request):books = Book.objects.all()return render(request, 'book_list.html', {'books': books})
在上面的代碼中,render
函數將模板 book_list.html
和 books
數據傳遞給模板。
7.3 模板語言
Django 模板語言(DTL)允許你在模板中使用變量、控制結構和過濾器。
-
變量:模板中可以嵌入 Python 變量,例如:
<h1>{{ book.title }}</h1>
-
控制結構:如循環和條件判斷:
{% for book in books %}<p>{{ book.title }}</p> {% endfor %}
-
過濾器:過濾器用于修改變量的輸出,例如:
<p>{{ book.published_date|date:"Y-m-d" }}</p>
第八章:Django 管理后臺
8.1 使用 Django Admin
Django 提供了一個功能強大的自動化管理后臺,你可以用它來管理模型數據。要啟用 Django Admin,你需要在 models.py
中注冊你的模型。
例如,注冊 Book
模型:
# myapp/admin.py
from django.contrib import admin
from .models import Bookadmin.site.register(Book)
之后,你可以在瀏覽器中訪問 /admin/
來登錄并管理你的數據。
8.2 創建超級用戶
要訪問 Django 的管理后臺,你需要先創建一個超級用戶:
python manage.py createsuperuser
然后按照提示設置用戶名、電子郵件和密碼。
繼續深入,我們將探討 Django 的一些更高級功能和應用開發中的常見需求。
第九章:Django 表單(Forms)
9.1 什么是 Django 表單?
Django 提供了一個強大的表單系統,使得處理用戶提交的表單變得簡單。表單不僅可以用來處理 HTML 表單數據,還可以用于驗證用戶輸入、自動生成表單控件等。
9.2 創建表單
你可以使用 forms.Form
來定義表單類。在表單類中,你可以定義字段(如 CharField
、EmailField
等)并指定驗證規則。
例如,創建一個簡單的用戶注冊表單:
# myapp/forms.py
from django import formsclass UserRegistrationForm(forms.Form):username = forms.CharField(max_length=100)email = forms.EmailField()password = forms.CharField(widget=forms.PasswordInput)
在這個表單中,我們有三個字段:
CharField
:用于文本輸入。EmailField
:用于電子郵件輸入,并且會自動驗證輸入是否合法。PasswordInput
:密碼輸入框。
9.3 處理表單提交
在視圖中,我們可以處理表單提交并驗證用戶輸入。例如:
# myapp/views.py
from django.shortcuts import render
from .forms import UserRegistrationFormdef register(request):if request.method == 'POST':form = UserRegistrationForm(request.POST)if form.is_valid():# 處理表單數據username = form.cleaned_data['username']email = form.cleaned_data['email']password = form.cleaned_data['password']# 假設這里有保存用戶邏輯return render(request, 'registration_success.html')else:form = UserRegistrationForm()return render(request, 'register.html', {'form': form})
在這個視圖中:
- 我們首先判斷請求方法是否為
POST
,即表單是否被提交。 - 如果表單有效,
form.is_valid()
返回True
,則可以通過form.cleaned_data
訪問用戶輸入的數據。 - 否則,顯示一個新的空表單。
9.4 渲染表單
模板文件 register.html
中,我們可以使用 Django 模板語言來渲染表單:
<form method="post">{% csrf_token %}{{ form.as_p }}<button type="submit">Register</button>
</form>
在模板中:
{% csrf_token %}
是 CSRF(跨站請求偽造)保護令牌,用于防止 CSRF 攻擊。{{ form.as_p }}
會將表單的每個字段渲染成一個<p>
標簽的形式。
9.5 表單驗證和錯誤處理
當表單無效時,Django 會自動處理錯誤,并將錯誤信息傳遞到模板中。例如,你可以在模板中這樣展示錯誤信息:
{% if form.errors %}<ul>{% for field in form %}{% for error in field.errors %}<li>{{ error }}</li>{% endfor %}{% endfor %}</ul>
{% endif %}
9.6 使用模型表單
模型表單(ModelForm)是 Django 提供的一種便捷方式,用于自動生成與模型字段對應的表單字段。例如,我們可以為 Book
模型創建一個表單:
# myapp/forms.py
from django import forms
from .models import Bookclass BookForm(forms.ModelForm):class Meta:model = Bookfields = ['title', 'author', 'published_date']
然后在視圖中使用該表單進行處理:
# myapp/views.py
from django.shortcuts import render, redirect
from .forms import BookFormdef create_book(request):if request.method == 'POST':form = BookForm(request.POST)if form.is_valid():form.save()return redirect('book_list')else:form = BookForm()return render(request, 'create_book.html', {'form': form})
第十章:Django 中的用戶認證(Authentication)
10.1 用戶認證概述
Django 內置了一個強大的認證系統,提供了用戶注冊、登錄、登出、密碼管理等功能。你可以輕松地使用這些功能來構建安全的 Web 應用。
10.2 用戶登錄和登出
Django 提供了一個視圖和表單來處理用戶登錄。你可以使用 Django 內置的 LoginView
和 LogoutView
來處理登錄和登出操作。
-
登錄視圖:
from django.contrib.auth.views import LoginViewurlpatterns = [path('login/', LoginView.as_view(), name='login'), ]
-
登出視圖:
from django.contrib.auth.views import LogoutViewurlpatterns = [path('logout/', LogoutView.as_view(), name='logout'), ]
Django 會自動為你處理認證過程。如果登錄成功,用戶將被重定向到 LOGIN_REDIRECT_URL
配置的 URL,通常是主頁。
10.3 用戶注冊
Django 沒有提供內置的用戶注冊視圖,但你可以通過編寫自定義視圖來處理用戶注冊。
例如,使用 UserCreationForm
來處理用戶注冊:
# myapp/forms.py
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import Userclass CustomUserCreationForm(UserCreationForm):email = forms.EmailField()class Meta:model = Userfields = ['username', 'email', 'password1', 'password2']
然后在視圖中使用這個表單:
# myapp/views.py
from django.shortcuts import render, redirect
from .forms import CustomUserCreationFormdef register(request):if request.method == 'POST':form = CustomUserCreationForm(request.POST)if form.is_valid():form.save()return redirect('login')else:form = CustomUserCreationForm()return render(request, 'register.html', {'form': form})
10.4 用戶權限和組
Django 還提供了權限控制功能,可以為不同的用戶賦予不同的訪問權限。你可以定義 Group
(組)和 Permission
(權限),然后為用戶分配。
-
權限檢查:
if request.user.has_perm('myapp.can_edit'):# 用戶有權限
-
組管理:
from django.contrib.auth.models import Group group = Group.objects.get(name='Editors') user.groups.add(group)
第十一章:Django 靜態文件和媒體文件
11.1 靜態文件
靜態文件(如 CSS、JavaScript 和圖片)通常是 Web 應用中的靜態資源,Django 提供了一個機制來管理這些文件。
-
配置靜態文件:在
settings.py
中,你需要配置靜態文件目錄:STATIC_URL = '/static/' STATICFILES_DIRS = [BASE_DIR / 'static', ]
-
使用靜態文件:在模板中,你可以使用
{% static %}
標簽引用靜態文件:<link rel="stylesheet" type="text/css" href="{% static 'css/styles.css' %}">
-
收集靜態文件:在部署時,使用
collectstatic
命令將所有靜態文件集中到一個目錄:python manage.py collectstatic
11.2 媒體文件
媒體文件(如上傳的文件)通常需要不同的配置。
-
配置媒體文件:
MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media'
-
處理文件上傳:在表單中使用
FileField
或ImageField
來處理文件上傳。class UserProfile(models.Model):user = models.OneToOneField(User, on_delete=models.CASCADE)avatar = models.ImageField(upload_to='avatars/')
在模板中,你可以通過 {{ userprofile.avatar.url }}
來顯示上傳的頭像。
好的,接下來我們繼續深入 Django,補充一些可能遺漏的重要知識點,并介紹一些在開發中非常常用的功能。Django 是一個功能豐富的框架,掌握更多的高級特性能夠幫助你更加高效地開發應用。
第十二章:Django 中的中間件(Middleware)
12.1 什么是中間件?
中間件是一個處理請求和響應的鉤子,它位于 Django 請求/響應生命周期的中間。中間件可以處理和修改請求,響應,或者執行一些額外的操作(如用戶認證、跨域請求支持、請求日志等)。
中間件在每個請求和響應的生命周期中都會被執行,并且可以在視圖函數執行之前或之后進行操作。
12.2 中間件的工作原理
中間件可以在以下環節處理請求或響應:
- 請求階段:在請求到達視圖函數之前,執行相關操作(如用戶認證、權限檢查等)。
- 響應階段:在視圖函數處理完請求后,響應返回給客戶端之前,執行相應的操作(如響應壓縮、添加頭信息等)。
在 settings.py
文件中,你可以配置全局的中間件列表(MIDDLEWARE
)。
12.3 創建自定義中間件
你可以通過創建一個 Python 類并實現其中的方法來創建自定義中間件。
# myapp/middleware.py
from django.http import HttpResponseclass SimpleMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):# 請求前的操作print("Request received")# 獲取響應response = self.get_response(request)# 響應后的操作print("Response sent")return response
然后,在 settings.py
中添加這個中間件:
MIDDLEWARE = [# 其他中間件...'myapp.middleware.SimpleMiddleware',
]
12.4 常見的內置中間件
Django 提供了許多常用的中間件,例如:
AuthenticationMiddleware
:處理用戶認證。SessionMiddleware
:處理會話管理。CSRFMiddleware
:防止跨站請求偽造(CSRF)攻擊。CommonMiddleware
:提供一些常見的功能,比如 URL 重定向、內容長度限制等。
第十三章:Django 的信號系統(Signals)
13.1 什么是信號?
信號是 Django 提供的一種通知機制,它允許一個部分的代碼發送通知,其他部分的代碼可以接收到這些通知并做出反應。信號的作用是解耦不同部分的代碼,避免直接調用和相互依賴。
例如,你可以在用戶注冊成功后,通過信號發送通知,或者在數據庫模型保存后自動做某些事情。
13.2 創建和使用信號
Django 提供了 django.db.models.signals
和 django.core.signals
這兩個信號系統,最常見的信號之一是 post_save
信號,它會在模型實例被保存后觸發。
首先,在 signals.py
中定義一個信號處理函數:
# myapp/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import User@receiver(post_save, sender=User)
def user_post_save(sender, instance, created, **kwargs):if created:print(f"New user created: {instance.username}")
然后,在 apps.py
文件中連接信號:
# myapp/apps.py
from django.apps import AppConfigclass MyAppConfig(AppConfig):name = 'myapp'def ready(self):import myapp.signals
這樣,當 User
模型實例保存時,user_post_save
函數會自動被調用。
第十四章:Django 測試(Testing)
14.1 Django 測試框架
Django 內置了一個功能強大的測試框架,基于 Python 的 unittest
,但對 Django 項目進行了適配。它可以幫助你在開發過程中測試視圖、模型、表單和其他功能。
14.2 創建測試用例
你可以為應用中的視圖、模型等編寫測試用例,確保代碼在不同場景下的正確性。
例如,創建一個針對 Book
模型的簡單測試:
# myapp/tests.py
from django.test import TestCase
from .models import Bookclass BookModelTest(TestCase):def test_book_creation(self):book = Book.objects.create(title="Test Book", author="Author", isbn="12345", pages=200)self.assertEqual(book.title, "Test Book")self.assertEqual(book.author, "Author")
14.3 測試視圖
你還可以測試視圖函數,確保它們返回正確的 HTTP 響應。
# myapp/tests.py
from django.test import TestCase
from django.urls import reverseclass BookViewTest(TestCase):def test_book_list_view(self):response = self.client.get(reverse('book_list'))self.assertEqual(response.status_code, 200)self.assertContains(response, "Books")
self.client.get()
:模擬一個 GET 請求。self.assertEqual()
:斷言響應狀態碼是否為 200。self.assertContains()
:斷言響應內容是否包含某些文本。
14.4 自動化測試
Django 支持自動化的測試運行。你可以通過以下命令來運行所有測試:
python manage.py test
第十五章:Django 緩存(Caching)
15.1 什么是緩存?
緩存是存儲一些計算結果或資源的機制,用于減少對數據庫的頻繁訪問,提高性能。Django 提供了多種緩存方法,如內存緩存、文件緩存、數據庫緩存等。
15.2 配置緩存
Django 支持多種緩存后端,可以在 settings.py
中進行配置。例如,使用內存緩存:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',}
}
15.3 使用緩存
你可以通過 cache
API 來緩存數據:
from django.core.cache import cache# 設置緩存
cache.set('my_key', 'my_value', timeout=60)# 獲取緩存
value = cache.get('my_key')# 刪除緩存
cache.delete('my_key')
15.4 頁面緩存和模板緩存
Django 還支持對整個視圖或模板進行緩存。
-
頁面緩存:使用
cache_page
裝飾器緩存視圖的輸出。from django.views.decorators.cache import cache_page@cache_page(60 * 15) # 緩存 15 分鐘 def my_view(request):# 視圖邏輯
-
模板緩存:在模板中使用
{% cache %}
標簽緩存部分模板內容。
第十六章:Django 部署
16.1 準備工作
在開發完成后,部署是將 Django 應用上線的關鍵步驟。部署 Django 應用通常涉及到以下內容:
- 配置生產環境的數據庫(通常是 PostgreSQL 或 MySQL)。
- 配置 Web 服務器(如 Nginx 或 Apache)。
- 配置 WSGI 服務器(如 Gunicorn)。
- 配置靜態文件和媒體文件。
16.2 配置數據庫
在 settings.py
中,配置數據庫為生產環境的數據庫(例如 PostgreSQL):
DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql','NAME': 'mydb','USER': 'myuser','PASSWORD': 'mypassword','HOST': 'localhost','PORT': '5432',}
}
16.3 生產環境設置
- 禁用調試模式:確保
DEBUG = False
,并設置ALLOWED_HOSTS
。 - 收集靜態文件:
python manage.py collectstatic
16.4 使用 WSGI 和 Gunicorn
Django 使用 WSGI 來與 Web 服務器通信。在生產環境中,通常會使用 Gunicorn 作為 WSGI 服務器。
安裝 Gunicorn:
pip install gunicorn
運行 Gunicorn:
gunicorn myproject.wsgi:application
16.5 配置 Nginx
Nginx 常用作反向代理,幫助處理靜態文件請求并將動態請求代理到 Gunicorn。
基本的 Nginx 配置:
server {listen 80;server_name mysite.com;location / {proxy_pass http://127.0.0.1:8000;}location /static/ {root /path/to/your/static/directory;}location /media/ {root /path/to/your/media/directory;}
}
好的,接下來我們繼續補充一些實際開發中常用的 Django 知識點和技術,幫助你在日常開發中更高效地使用 Django。
第十七章:Django 的 REST API 開發
隨著 Web 應用的發展,許多項目需要開發 RESTful API,以便與前端或其他應用進行通信。Django 提供了一個非常強大的庫——Django Rest Framework (DRF),用于快速構建 API。
17.1 安裝 Django Rest Framework
首先,你需要安裝 Django Rest Framework。
pip install djangorestframework
然后在 settings.py
中添加 rest_framework
到 INSTALLED_APPS
:
INSTALLED_APPS = [# 其他應用...'rest_framework',
]
17.2 創建簡單的 API 視圖
使用 DRF,你可以通過視圖類或函數輕松構建 API 視圖。最常見的方式是使用 APIView
類。
例如,創建一個返回所有書籍的簡單 API 視圖:
# myapp/views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Book
from .serializers import BookSerializerclass BookList(APIView):def get(self, request):books = Book.objects.all()serializer = BookSerializer(books, many=True)return Response(serializer.data, status=status.HTTP_200_OK)
17.3 創建 Serializer
在 DRF 中,Serializer
是將模型實例轉化為 JSON 數據的工具。
# myapp/serializers.py
from rest_framework import serializers
from .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published_date', 'isbn']
17.4 配置 URL 路由
你需要將 API 視圖與 URL 進行綁定。
# myapp/urls.py
from django.urls import path
from .views import BookListurlpatterns = [path('api/books/', BookList.as_view(), name='book_list_api'),
]
現在,當你訪問 /api/books/
時,Django 將返回所有書籍的 JSON 數據。
17.5 使用 DRF 的認證和權限
Django Rest Framework 提供了多種認證和權限控制方式(如 Token 認證、OAuth 等)。
- Token 認證:可以使用
rest_framework.authtoken
來實現 Token 認證。- 安裝
djangorestframework-authtoken
:pip install djangorestframework-authtoken
- 在
INSTALLED_APPS
中添加:'rest_framework.authtoken',
- 在 URL 中添加 Token 認證視圖:
from rest_framework.authtoken.views import obtain_auth_token urlpatterns = [path('api-token-auth/', obtain_auth_token), ]
- 安裝
17.6 分頁、過濾和排序
Django Rest Framework 提供了強大的分頁、過濾和排序功能。
-
分頁:可以在
settings.py
中配置全局分頁設置。REST_FRAMEWORK = {'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination','PAGE_SIZE': 10, }
-
過濾:可以使用
django_filters
來處理過濾功能。pip install django-filter
然后在視圖中使用:
from rest_framework import viewsets from .models import Book from .serializers import BookSerializer from django_filters.rest_framework import DjangoFilterBackendclass BookViewSet(viewsets.ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializerfilter_backends = [DjangoFilterBackend]filterset_fields = ['author', 'published_date']
-
排序:通過
ordering
可以添加排序功能。class BookViewSet(viewsets.ModelViewSet):queryset = Book.objects.all()serializer_class = BookSerializerordering_fields = ['title', 'published_date']
第十八章:Django 中的異步支持
隨著 Python 異步支持的增強,Django 也開始逐步支持異步功能,尤其在處理高并發請求時,異步操作顯得尤為重要。
18.1 異步視圖
從 Django 3.1 開始,Django 支持異步視圖和中間件。異步視圖可以在執行 I/O 密集型任務時避免阻塞,從而提高應用性能。
例如,創建一個異步視圖來模擬網絡請求:
# myapp/views.py
from django.http import JsonResponse
import asyncioasync def my_async_view(request):await asyncio.sleep(2) # 模擬一些 I/O 密集型操作return JsonResponse({'message': 'Hello, Async World!'})
18.2 異步數據庫查詢
Django 目前(截至 2023)對數據庫查詢的支持仍然是同步的,無法直接執行異步數據庫查詢。但你可以使用 asgiref.sync.sync_to_async
將同步的數據庫查詢轉為異步。
例如,異步調用一個同步的數據庫查詢:
from asgiref.sync import sync_to_async@sync_to_async
def get_books():return Book.objects.all()
然后在異步視圖中調用:
async def book_list(request):books = await get_books()return JsonResponse({'books': [book.title for book in books]})
第十九章:Django 的高級查詢
19.1 聚合和注解
Django 的 ORM 提供了強大的聚合和注解功能,能夠幫助你高效地進行數據匯總和分組。
-
聚合:使用
aggregate
來進行聚合操作,如計數、求和、平均值等。from django.db.models import Count, Avg# 獲取每個作者的書籍數量 author_books_count = Book.objects.values('author').annotate(count=Count('id'))
-
注解:通過
annotate
為查詢結果中的每一行添加額外的計算字段。# 獲取每個作者的平均頁數 author_avg_pages = Book.objects.values('author').annotate(avg_pages=Avg('pages'))
19.2 子查詢和 Exists
Django ORM 允許你在查詢中使用子查詢和 Exists
。
-
子查詢:使用
Subquery
在查詢中嵌套另一個查詢。from django.db.models import Subquery, OuterRef# 獲取作者的第一本書 first_book = Book.objects.filter(author=OuterRef('author')).order_by('published_date') authors_books = Author.objects.annotate(first_book_title=Subquery(first_book.values('title')[:1]))
-
Exists
:用于檢查某個查詢是否返回結果。from django.db.models import Existsauthors_books = Author.objects.annotate(has_books=Exists(Book.objects.filter(author=OuterRef('pk'))))
19.3 復雜查詢的性能優化
-
select_related
和prefetch_related
:用于優化查詢性能,減少數據庫的查詢次數。select_related
:用于一對一或外鍵關系的優化查詢。
books = Book.objects.select_related('author').all()
prefetch_related
:用于多對多或反向外鍵關系的優化查詢。
books = Book.objects.prefetch_related('tags').all()
-
only
和defer
:優化查詢字段,限制加載的數據。only
:只加載指定字段,減少查詢的數據量。
books = Book.objects.only('title', 'author')
defer
:加載除指定字段外的所有字段。
books = Book.objects.defer('description')
第二十章:Django 與前端集成
20.1 Django 與 JavaScript 的集成
Django 通常會與前端框架(如 React、Vue.js)一起使用,或者與傳統的 JavaScript 集成。
-
Django 模板與 JavaScript 配合使用:你可以將數據從 Django 模板傳遞到前端 JavaScript。
<script>const books = {{ books | json_script:"books_data" }}; </script>
-
使用 AJAX 與 Django 后端通信:你可以通過 JavaScript 使用 AJAX 向 Django 后端發送請求并獲取響應。
fetch('/api/books/').then(response => response.json()).then(data => console.log(data));
20.2 Django 與前端框架(React/Vue)的集成
在現代應用中
,Django 通常作為后端 API 服務,前端通過 React、Vue 或 Angular 來構建單頁面應用(SPA)。
你可以使用 Django Rest Framework 構建 API,然后讓前端通過 HTTP 請求(如 fetch
或 Axios)與 Django 后端交互。
好的,接下來我會詳細講解 Django 與前端框架 Vue.js 的集成。這種集成通常是在現代 Web 應用中廣泛使用的一種模式,前端使用 Vue.js 來構建動態交互的界面,后端使用 Django 提供 API 支持,前后端通過 API 進行數據交互。
一、Django 與 Vue.js 集成的整體架構
Django 主要負責處理后端業務邏輯和提供數據 API,Vue.js 負責處理前端頁面的渲染和交互,通常這種架構下,Django 會作為 RESTful API 后端,提供數據接口,而 Vue.js 會作為 前端 SPA(單頁面應用),通過 API 與后端交互。
1. Django 作為后端 API(使用 Django Rest Framework)
在這種架構下,Django 通過 Django Rest Framework (DRF) 來提供 RESTful API,Vue.js 前端通過 HTTP 請求(比如使用 axios
或 fetch
)向 Django 請求數據。
2. Vue.js 作為前端
Vue.js 會從 Django 后端獲取數據并渲染到頁面上。Vue.js 負責前端視圖的更新和用戶交互,Django 則專注于提供數據支持。
這種結構有助于前后端分離,可以讓前端和后端獨立開發,易于擴展和維護。
二、如何實現 Django 與 Vue.js 的集成?
2.1 創建 Django 項目并設置 API
-
創建 Django 項目:
首先,我們創建一個新的 Django 項目(如果你已經有一個現有項目,可以跳過這一步)。django-admin startproject myproject cd myproject
-
安裝 Django Rest Framework:
安裝djangorestframework
庫,它幫助我們構建 RESTful API。pip install djangorestframework
然后在
settings.py
中添加rest_framework
:INSTALLED_APPS = [...'rest_framework', ]
-
創建一個 Django 應用:
現在我們創建一個名為books
的 Django 應用來處理書籍的數據。python manage.py startapp books
-
定義模型 (Model):
在books/models.py
文件中定義一個簡單的Book
模型:from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=100)author = models.CharField(max_length=100)published_date = models.DateField()def __str__(self):return self.title
-
創建數據庫遷移并應用遷移:
通過以下命令創建數據庫表:python manage.py makemigrations python manage.py migrate
-
創建序列化器 (Serializer):
在books/serializers.py
中創建一個BookSerializer
類,用于將Book
模型轉化為 JSON 格式:from rest_framework import serializers from .models import Bookclass BookSerializer(serializers.ModelSerializer):class Meta:model = Bookfields = ['id', 'title', 'author', 'published_date']
-
創建 API 視圖:
在books/views.py
中創建一個 API 視圖來提供書籍數據:from rest_framework.views import APIView from rest_framework.response import Response from .models import Book from .serializers import BookSerializerclass BookList(APIView):def get(self, request):books = Book.objects.all()serializer = BookSerializer(books, many=True)return Response(serializer.data)
-
設置 URL 路由:
在books/urls.py
中設置 API 路由:from django.urls import path from .views import BookListurlpatterns = [path('api/books/', BookList.as_view(), name='book_list_api'), ]
在
myproject/urls.py
中包含books
應用的 URL:from django.urls import path, includeurlpatterns = [path('books/', include('books.urls')),# 其他路由... ]
-
運行 Django 服務器:
啟動 Django 開發服務器:python manage.py runserver
此時,
http://127.0.0.1:8000/books/api/books/
就可以返回書籍的 JSON 數據了。
2.2 創建 Vue.js 項目
-
安裝 Node.js 和 Vue CLI:
如果沒有安裝Node.js
和Vue CLI
,可以從官網下載安裝:- Node.js 下載
- Vue CLI 下載
-
創建 Vue 項目:
在 Django 項目外部創建一個 Vue 項目:vue create vue-frontend
選擇默認配置,進入項目目錄:
cd vue-frontend
-
安裝 Axios:
Vue.js 需要axios
來向 Django 后端發送 HTTP 請求。可以通過以下命令安裝axios
:npm install axios
-
配置 Vue.js 與 Django 后端交互:
在src/components
中創建一個新的 Vue 組件,例如BookList.vue
,用于展示從 Django 獲取的數據。<template><div><h1>Books</h1><ul><li v-for="book in books" :key="book.id">{{ book.title }} by {{ book.author }}</li></ul></div> </template><script> import axios from 'axios';export default {data() {return {books: [],};},created() {this.fetchBooks();},methods: {async fetchBooks() {try {const response = await axios.get('http://127.0.0.1:8000/books/api/books/');this.books = response.data;} catch (error) {console.error("There was an error fetching books:", error);}}} }; </script>
這里使用
axios.get
從 Django 后端的/books/api/books/
接口獲取書籍數據,并將它們存儲在books
數組中。 -
運行 Vue 項目:
通過以下命令啟動 Vue.js 開發服務器:npm run serve
默認情況下,Vue.js 運行在
http://localhost:8080
,你可以在瀏覽器中訪問它。 -
跨域請求問題:
由于前端和后端的端口不同,Vue.js 發送的請求會受到跨域(CORS)的限制。你可以使用 Django 的django-cors-headers
庫來處理跨域問題。安裝
django-cors-headers
:pip install django-cors-headers
然后在
settings.py
中添加它:INSTALLED_APPS = [...'corsheaders', ]MIDDLEWARE = [...'corsheaders.middleware.CorsMiddleware', ]CORS_ALLOWED_ORIGINS = ['http://localhost:8080', # 允許 Vue 前端的跨域請求 ]
現在,前端 Vue.js 可以順利向 Django 后端發起請求。
三、前后端部署
-
部署 Django 后端:
- 將 Django 項目部署到生產環境(例如,使用
Gunicorn
和Nginx
)。 - 配置數據庫(如 PostgreSQL)并收集靜態文件(
python manage.py collectstatic
)。
- 將 Django 項目部署到生產環境(例如,使用
-
部署 Vue.js 前端:
- 構建 Vue.js 項目:
npm run build
。 - 將構建后的文件(通常在
dist
目錄中)部署到 Web 服務器(例如,使用Nginx
或Apache
)。
- 構建 Vue.js 項目:
四、總結
- Django 提供后端 API:使用 Django 和 Django Rest Framework 構建 API,提供數據。
- Vue.js 作為前端:使用 Vue.js 來構建前端視圖,異步請求后端數據。
- 跨域處理:使用
django-cors-headers
處理前后端的跨域問題。 - 部署:分別部署 Django 后端和 Vue.js 前端,并通過 API 進行通信。