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})

 

posted @ 2020-06-15 14:32  Tracydzf  阅读(768)  评论(0编辑  收藏  举报