動態

詳情 返回 返回

【Django開發】django美多商某城項目完整開發4.0第10篇:shou貨地址,省市區地址查詢【附代碼文檔】 - 動態 詳情

🏆🏆🏆教程全知識點簡介: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">|&nbsp;&nbsp;&nbsp;&nbsp;用户中心</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>
user avatar aloudata 頭像 openfuyao 頭像 inslog 頭像 bugDiDiDi 頭像 rivers_chaitin 頭像 huangmingji 頭像 shuyuanutil 頭像 leoych 頭像 tangzhiyuan 頭像 fabarta 頭像 bygpt 頭像 chang_lehung 頭像
點贊 29 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.