django实现地址省市区三级联动和drf-extensions扩展实现缓存

django实现地址省市区三级联动和drf-extensions扩展实现缓存

  • 前文
  • 创建一个应用areas
    • models模型类创建省市区数据表,自关联方式
    • 迁移数据库,并且导入数据库
    • 写后端的views
    • 写两个序列化器
    • 在urls文件配置路由
    • 用网页接口文档查看效果
  • drf-extensions扩展实现缓存
    • APIView直接给请求添加装饰器
    • 可以设定默认时间和指定存储数据库
    • 使用扩展类添加缓存方式
    • 给省市区视图添加缓存实例

前文

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

创建一个应用areas

cd到apps文件夹下创建

python ../../manage.py startapp areas

安装完之后注意配置设置文件:

INSTALLED_APPS = [
       ‘areas.apps.AreasConfig‘,#省市区数据
]

还有系统urls的配置和admin后台管理也要写一下

models模型类创建省市区数据表,自关联方式

from django.db import models

# Create your models here.

class Areas(models.Model):
    name = models.CharField(max_length=50, verbose_name='地名')
    # 外键链接自己,ondelete是当删除时和主表的行为
    pid = models.ForeignKey('self', verbose_name='父级的行政区域id', on_delete=models.SET_NULL, related_name='addinfo', null=True, blank=True)
    # on_delete = models.CASCADE  # 删除关联数据的时候,与之的关联也删除
    # on_delete = models.DO_NOTHING  # 不作操作
    # on_delete = models.PROTECT  # 删除关联就保存,保护
    # on_delete = models.SET_DEFAULT  # 与之关联设为默认值
    # on_delete = models.SET_NULL  # 与之关联设为空

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'areas'
        verbose_name_plural = '地区'

模型类代码说明:

pid = models.ForeignKey('self', verbose_name='父级的行政区域id', on_delete=models.SET_NULL, related_name='addinfo', null=True, blank=True)
  • self:自关联
  • on_delete=models.SET_NULL
    在删除父级的时候,自己的pid_id设置为空,这里就不在级联删除了,避免误删除,采集数据不容易。
  • related_name=’addinfo’ ,意思为如果想找自己的子级,就可以通过area.addinfo找到自己下级所有的area区域。
  • related_name必须要设置下面序列化器的一样
  • null必须设置为True,因为省级行政单位没有父级

迁移数据库,并且导入数据库

每次对models模型文件修改都要进行数据迁移,终端执行

python manage.py makemigrations
python manage.py migrate

然后下载数据库文件省市区的areas.sql:
https://download.csdn.net/download/paul0926/11251780
终端到这个文件的目录里然后倒入到你的数据库中

mysql -uroot -p shanghui < areas.sql

导完查看一下是否成功

写后端的views

这里使用ReadOnlyModelViewSet,因为能根据不同的请求指定不同的序列化器,

from django.shortcuts import render
from rest_framework.viewsets import *


from .serializers import *
from .models import *
# Create your views here.

class AreasInfoView(ReadOnlyModelViewSet):
    """提供省市区三级联动数据"""

    # 禁用分页
    pagination_class = None

    # 指定要输出的数据来自哪个查询集
    # queryset = Area.objects.all()
    def get_queryset(self):
        """根据请求的行为,过滤不同的行为对应的序列化器需要的数据"""
        if self.action == 'list':
            return Areas.objects.filter(pid=None)  # 只有当pid=None 返回的是省级数据
        else:
            return Areas.objects.all()

    # 指定序列化器
    # serializer_class = ‘序列化器‘
    def get_serializer_class(self):
        """根据请求的行为,指定不同的序列化器"""
        if self.action == 'list':
            return AreaInfoSer
        else:
            return NextAreasInfoSer

写两个序列化器

在areas文件夹下新建serializers.py文件写序列化器类

from rest_framework import serializers
from . import models

class AreaInfoSer(serializers.ModelSerializer):
    class Meta:
        model = models.Areas
        fields = ('id', 'name')


class NextAreasInfoSer(serializers.ModelSerializer):
    # 嵌套序列化器,得到自己想要的数据
    addinfo = AreaInfoSer(many=True, read_only=True)

    # 这个是返回字符串显示的是__str__方法返回的内容。
    # addinfo = serializers.StringRelatedField(many=True, read_only=True)
    # 不写的时候默认是PrimaryKeyrelatedField,也就是显示id

    # 要展现他的下一级
    class Meta:
        model = models.Areas
        fields = ('id', 'name', 'addinfo')

第一个序列化器就是展示地区名,第二个序列化器是为了展示他的下一级,比如查看浙江省,附带他的市级行政区,注意这个返回第一个序列化器内容的名字需要和上面模型类的related_name名字一致

在urls文件配置路由

当使用viewsets类的时候都推荐使用路由自动配置路径

from django.conf.urls import url, include
from .views import *
from rest_framework import routers


router = routers.DefaultRouter()
# 第一个参数是路径
router.register(r'info', AreasInfoView, base_name='info')

urlpatterns = [
    url(r'', include(router.urls))
]

用网页接口文档查看效果

django如何配置接口文档查看:https://blog.csdn.net/paul0926/article/details/92761909
django实现地址省市区三级联动和drf-extensions扩展实现缓存_第1张图片
调试一下单个id查询,也就是查某个省级下所有的市级行政单位:
django实现地址省市区三级联动和drf-extensions扩展实现缓存_第2张图片
出现这种效果则成功。

drf-extensions扩展实现缓存

省市区的数据是经常被用户查询使用的,而且数据基本不变化,所以我们可以将省市区数据进行缓存处理,减少数据库的查询次数。
查看官方文档:http://chibisov.github.io/drf-extensions/docs/#caching
先pip安装:

pip install drf-extensions

APIView直接给请求添加装饰器

先导包然后给具体请求方法加装饰器

from rest_framework_extensions.cache.decorators import cache_response

class EmailVerifyView(APIView):
    # 激活邮箱
    @cache_response(timeout=60*60, cache='default')
    def get(self, request, token):

有两个参数:

  • timeout 缓存时间,单位秒
  • cache 缓存使用的Django缓存后端(即CACHES配置中的键名称)即选择的是redis数据库的几号数据库(一共16个数据库)

可以设定默认时间和指定存储数据库

在自己的设置文件里添加即可:

# DRF扩展
REST_FRAMEWORK_EXTENSIONS = {
    # 缓存时间
    'DEFAULT_CACHE_RESPONSE_TIMEOUT': 60 * 60,
    # 缓存存储
    'DEFAULT_USE_CACHE': 'default',
}

使用扩展类添加缓存方式

drf-extensions扩展对于缓存提供了三个扩展类:

  • ListCacheResponseMixin
  • 用于缓存返回列表数据的视图,与ListModelMixin扩展类配合使用,实际是为list方法添加了cache_response装饰器
  • RetrieveCacheResponseMixin
  • 用于缓存返回单一数据的视图,与RetrieveModelMixin扩展类配合使用,实际是为retrieve方法添加了cache_response装饰器
  • CacheResponseMixin
  • 为视图集同时补充List和Retrieve两种缓存,与ListModelMixin和RetrieveModelMixin一起配合使用。
  • 三个扩展类都是在rest_framework_extensions.cache.mixins中。

给省市区视图添加缓存实例

导包,类多继承一个即可

# 添加缓存
from rest_framework_extensions.cache.mixins import CacheResponseMixin

class AreasInfoView(ReadOnlyModelViewSet, CacheResponseMixin):
    """提供省市区三级联动数据"""

你可能感兴趣的:(Django)