省市区地址查询

在用户录入地址时,需要进行省市区的选择。在页面加载时,向后端请求省份数据,当用户选择确定省份后,向后端请求该省份的城市数据;在用户选择确定城市数据后,向后端请求该城市的区县信息。我们把这个过程称为省市区三级联动。

我们新建一个应用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)请求城市或区县数据

请求方式: 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中新建视图

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

转载于:https://www.cnblogs.com/hzlnice/p/9393027.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值