Django--省市区三级联动
模型类的创建
class Area(models.Model): """ 行政区划 """ # 创建 name 字段, 用户保存名称 name = models.CharField(max_length=20, verbose_name='名称') # 自关联字段 parent # 第一个参数是 self : parent关联自己. # on_delete=models.SET_NULL: 如果省删掉了,省内其他的信息为 NULL # related_name='subs': 设置之后 # 我们就这样调用获取市: area.area_set.all() ==> area.subs.all() 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语法。
请求省份数据
请求方式: GET /areas/
from django.views import View from areas.models import Area from django import http class ProvinceAreasView(View): """省级地区""" def get(self, request): """提供省级地区数据 1.查询省级数据 2.序列化省级数据 3.响应省级数据 4.补充缓存逻辑 """
# 增加: 判断是否有缓存
province_list = cache.get('province_list')
if not province_list:
try:
province_model_list = Area.objects.filter(parent__isnull=True)
province_list = []
for province_model in province_model_list:
province_list.append({'id': province_model.id,
'name': province_model.name})
# 增加: 缓存省级数据
cache.set('province_list', province_list, 3600)
except Exception as e:
return http.JsonResponse({'code': 400,
'errmsg': '省份数据错误'})
return http.JsonResponse({'code': 0,
'errmsg': 'OK',
'province_list': province_list})
请求市区数据
请求方式: GET /areas/(?P<pk>[1-9]\d+)/
class SubAreasView(View): """子级地区:市和区县""" def get(self, request, pk): """提供市或区地区数据 1.查询市或区数据 2.序列化市或区数据 3.响应市或区数据 4.补充缓存数据 """ # 判断是否有缓存 sub_data = cache.get('sub_area_' + pk) if not sub_data: # 1.查询市或区数据 try: sub_model_list = Area.objects.filter(parent=pk) # 查询市或区的父级 parent_model = Area.objects.get(id=pk) # 2.序列化市或区数据 sub_list = [] for sub_model in sub_model_list: sub_list.append({'id': sub_model.id, 'name': sub_model.name}) sub_data = { 'id':parent_model.id, # pk 'name':parent_model.name, 'subs': sub_list } # 缓存市或区数据 cache.set('sub_area_' + pk, sub_data, 3600) except Exception as e: return http.JsonResponse({'code': 400, 'errmsg': '城市或区县数据错误'}) # 3.响应市或区数据 return http.JsonResponse({'code': 0, 'errmsg': 'OK', 'sub_data': sub_data})