省市區地址查詢


在用戶錄入地址時,需要進行省市區的選擇。在頁面加載時,向后端請求省份數據,當用戶選擇確定省份后,向后端請求該省份的城市數據;在用戶選擇確定城市數據后,向后端請求該城市的區縣信息。我們把這個過程稱為省市區三級聯動。

我們新建一個應用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)請求城市或區縣數據

請求方式: 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中新建視圖

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM