🏆🏆🏆教程全知識點簡介:1.郵件驗證系統包括Django發送郵件、保存郵箱併發送驗證郵件、Celery使用Django配置文件設置。2. 地址管理涵蓋shou貨地址、省市區地址查詢、數據庫建表、後端接口設計、前端實現、緩存使用(安裝、使用方法、省市區視圖緩存、緩存數據保存位置和有效期設置)、用户地址管理。3. 數據庫設計包括用户部分、產品部分、數據庫表設計、表結構、數據庫模型類。4. 容器化部署涵蓋Docker使用(Ubuntu安裝、啓動停止、鏡像操作)、FastDFS客户端與自定義文件存儲系統、頁面靜態化、定時任務、靜態化首頁腳本。5. 產品系統包括產品詳情頁、異步任務觸發、腳本工具、用户瀏覽歷史記錄(保存、查看)。6. 產品模式涵蓋B2B企業對企業、C2C個人對個人、O2O線上到線下、開發流程、需求分析。7. 購wu車系統包括購wu車管理、購wu車數據存儲設計(Redis保存已登錄用户)、添加到購wu車、查詢購wu車數據、登錄合併購wu車。8. 訂order單系統涵蓋提交訂order單、我的訂order單、訂order單評價、訂order單結算、保存訂order單、MySQL事務隔離級別修改、下單成功頁面。9. 搜索系統包括產品搜索、搜索引擎原理、Elasticsearch、Docker安裝Elasticsearch擴展、前端實現。10. 支fu系統涉及 集成、Xadmin管理後台。11. 項目配置包括項目準備、配置文件修改、數據庫配置、Redis配置、本地化語言時區、異常處理、日誌記錄。12. 用户認證系統涵蓋圖片驗證碼、域名設置、前端Vue代碼、跨域CORS、Celery發送短信、賬號存在判斷、JWT認證(JWT概念、構成、應用、Django REST framework JWT)、 登錄(登錄流程、模型類創建、urllib使用、回調處理)、用户中心個人信息。
<!-- start:bj1 -->
📚📚👉👉👉本站這篇博客: https://segmentfault.com/a/1190000046720728 中查看
📚📚👉👉👉本站這篇博客: https://segmentfault.com/a/1190000046720728 中查看
<!-- end:bj1 -->
✨ 本教程項目亮點
🧠 知識體系完整:覆蓋從基礎原理、核心方法到高階應用的全流程內容
💻 全技術鏈覆蓋:完整前後端技術棧,涵蓋開發必備技能
🚀 從零到實戰:適合 0 基礎入門到提升,循序漸進掌握核心能力
📚 豐富文檔與代碼示例:涵蓋多種場景,可運行、可複用
🛠 工作與學習雙參考:不僅適合系統化學習,更可作為日常開發中的查閲手冊
🧩 模塊化知識結構:按知識點分章節,便於快速定位和複習
📈 長期可用的技術積累:不止一次學習,而是能伴隨工作與項目長期參考
🎯🎯🎯全教程總章節
🚀🚀🚀本篇主要內容
shou貨地址
在這個頁面中, 要實現用户地址的管理,主要的業務邏輯有:
- 省市區地址的數據庫建立與查詢
- 用户地址的增刪改查處理
- 設置默認地址
-
設置地址標題
主要講解省市區地址的三級聯動和緩存,其餘留給大家自己來實現。
學習目標:
- 省市區三級聯動
- 在Django REST framework中使用緩存
省市區地址查詢
在用户錄入地址時,需要進行省市區的選擇。在頁面加載時,向後端請求省份數據,當用户選擇確定省份後,向後端請求該省份的城市數據;在用户選擇確定城市數據後,向後端請求該城市的區縣信息。 把這個過程稱為省市區三級聯動。
新建一個應用areas來實現省市區三級聯動。
數據庫建表
在areas/models.py中, 創建省市區數據表,採用自關聯方式。
class Area(models.Model):
"""
行政區劃
"""
name = models.CharField(max_length=20, verbose_name='名稱')
parent = models.ForeignKey('self', on_delete=models.SET_NULL, related_name='subs', null=True, blank=True, verbose_name='上級行政區劃')
class Meta:
db_table = 'tb_areas'
verbose_name = '行政區劃'
verbose_name_plural = '行政區劃'
def __str__(self):
return self.name
説明
- 自關聯字段的外鍵指向自身,所以
ForeignKey('self') - 需要使用
related_name指明查詢一個行政區劃的所有下級行政區劃時,使用哪種語法查詢,如本模型類中指明通過Area模型類對象.subs查詢所有下屬行政區劃,而不是使用Django默認的Area模型類對象.area_set語法。
遷移到數據庫後, 向數據庫中添加全國省市區數據,將areas.sql導入數據庫中。
可以將導入數據庫的過程創建一個腳本,在scripts目錄中創建import_areas_data_to_db.sh文件
mysql -h數據庫ip地址 -u數據庫用户名 -p 數據庫 < areas.sql
# mysql -h10.211.55.5 -umeiduo -p meiduo_mall < areas.sql
如:
#!/bin/bash
mysql -h10.211.55.5 -umeiduo -p meiduo_mall < areas.sql
修改文件的執行權限
chmod +x import_areas_data_to_db.sh
然後執行如下命令導入數據
./import_areas_data_to_db.sh
後端接口設計
1)請求省份數據
請求方式: GET /areas/
請求參數: 無
返回數據: JSON
[
{
"id": 110000,
"name": "北京市"
},
{
"id": 120000,
"name": "天津市"
},
{
"id": 130000,
"name": "河北省"
},
...
]
| 返回值 | 類型 | 是否必傳 | 説明 |
|---|---|---|---|
| id | int | 是 | 省份id |
| name | str | 是 | 省份名稱 |
2)請求城市或區縣數據
Databases 異步庫
請求方式: GET /areas/(?P<pk>\d+)/
請求參數: 路徑參數
| 參數 | 類型 | 是否必傳 | 説明 |
|---|---|---|---|
| pk | int | 是 | 上級區劃id(省份id用於獲取城市數據,或城市id用於獲取區縣數據) |
返回數據: JSON
| 返回值 | 類型 | 是否必傳 | 説明 |
|---|---|---|---|
| id | int | 是 | 上級區劃id(省份id或城市id) |
| name | str | 是 | 上級區劃的名稱 |
| subs | list[] | 是 | 下屬所有區劃信息 |
如:
{
"id": "110100",
"name": "北京市",
"subs": [
{
"id": "110101",
"name": "東城區"
},
{
"id": "110102",
"name": "西城區"
}
]
}
在areas/serializers.py中新建序列化器
from rest_framework import serializers
from .models import Area
class AreaSerializer(serializers.ModelSerializer):
"""
行政區劃信息序列化器
"""
class Meta:
model = Area
fields = ('id', 'name')
class SubAreaSerializer(serializers.ModelSerializer):
"""
子行政區劃信息序列化器
"""
subs = AreaSerializer(many=True, read_only=True)
class Meta:
model = Area
fields = ('id', 'name', 'subs')
在areas/views.py中新建視圖
Selenium Python 文檔
from django.shortcuts import render
from rest_framework.viewsets import ReadOnlyModelViewSet
from .models import Area
from .serializers import AreaSerializer, SubAreaSerializer
# Create your views here.
class AreasViewSet(ReadOnlyModelViewSet):
"""
行政區劃信息
"""
pagination_class = None # 區劃信息不分頁
def get_queryset(self):
"""
提供數據集
"""
if self.action == 'list':
return Area.objects.filter(parent=None)
else:
return Area.objects.all()
def get_serializer_class(self):
"""
提供序列化器
"""
if self.action == 'list':
return AreaSerializer
else:
return SubAreaSerializer
定義路由
router = DefaultRouter()
router.register(r'areas', views.AreasViewSet, base_name='areas')
urlpatterns = []
urlpatterns += router.urls
前端
修改user_center_site.html文件,增加vue變量
Codecademy Python
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>美多商某城-用户中心</title>
<link rel="stylesheet" type="text/css" href="css/reset.css">
<link rel="stylesheet" type="text/css" href="css/main.css">
<script type="text/javascript" src="js/host.js"></script>
<script type="text/javascript" src="js/vue-2.5.16.js"></script>
<script type="text/javascript" src="js/axios-0.18.0.min.js"></script>
<script>
var user_id = sessionStorage.user_id || localStorage.user_id;
var token = sessionStorage.token || localStorage.token;
if (!(user_id && token)) {
location.href = '/login.html?next=/user_center_site.html';
}
</script>
</head>
<body>
<div id="app" v-cloak>
<div class="header_con">
<div class="header">
<div class="welcome fl">歡迎來到美多商某城!</div>
<div class="fr">
<div class="login_btn fl">
歡迎您:<em>{{ username }}</em>
<span>|</span>
<a @click="logout">退出</a>
</div>
<div class="user_link fl">
<span>|</span>
<a href="user_center_info.html">用户中心</a>
<span>|</span>
<a href="cart.html">我的購wu車</a>
<span>|</span>
<a href="user_center_order.html">我的訂order單</a>
</div>
</div>
</div>
</div>
<div class="search_bar clearfix">
<a href="index.html" class="logo fl"><img src="images/logo.png"></a>
<div class="sub_page_name fl">| 用户中心</div>
<form method="get" action="/search.html" class="search_con fr mt40">
<input type="text" class="input_text fl" name="q" placeholder="搜索產品">
<input type="submit" class="input_btn fr" name="" value="搜索">
</form>
</div>
<div class="main_con clearfix">
<div class="left_menu_con clearfix">
<h3>用户中心</h3>
<ul>
<li><a href="user_center_info.html">· 個人信息</a></li>
<li><a href="user_center_order.html">· 全部訂order單</a></li>