【Django开发】django美多商某城项目完整开发4.0第10篇:shou货地址,省市区地址查询【附代码文档】

41 阅读1分钟

🏆🏆🏆教程全知识点简介: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使用、回调处理)、用户中心个人信息。


📚📚👉👉👉本站这篇博客:   juejin.cn/post/751004…    中查看

📚📚👉👉👉本站这篇博客:   juejin.cn/post/751004…    中查看

✨ 本教程项目亮点

🧠 知识体系完整:覆盖从基础原理、核心方法到高阶应用的全流程内容
💻 全技术链覆盖:完整前后端技术栈,涵盖开发必备技能
🚀 从零到实战:适合 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": "河北省"
    },
    ...
]
返回值类型是否必传说明
idint省份id
namestr省份名称
2)请求城市或区县数据

Databases 异步库

请求方式: GET /areas/(?P<pk>\d+)/

请求参数: 路径参数

参数类型是否必传说明
pkint上级区划id(省份id用于获取城市数据,或城市id用于获取区县数据)

返回数据: JSON

返回值类型是否必传说明
idint上级区划id(省份id或城市id)
namestr上级区划的名称
subslist[]下属所有区划信息

如:

{
    "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