django地址模块后端实现

地址模块的模型

由于在测试项目中并没有地址模块的html,就从别的地方弄了一个没有CSS样式的地址html坐下测试,大家将就一下
在这里插入图片描述

地址模块逻辑

我们这个地址模块中,主要是数据的调取,然后把数据存储到数据库中,所以存储的逻辑其实还是蛮简单的,不过我们的数据库中的逻辑就没这么简单了。
地址其实相当多,而且规格划分也非常多,我们不可能省一个表,然后每个省都给一个市表,每个市表都给一个区表,这不太现实。其实现在绝大多数地方都是用的内联表,比如省可以外键为空,市的外键是省,区的外键是市,这样查询省的时候就可以查询到省下的市,查询市就可以查询到区。
那么我们现在就要实现这个查询

建立一个查询表格将来用来查询地址

我新建一个地址模块来写查询逻辑
在这里插入图片描述
新建模块areas
setting中注册

INSTALLED_APPS = [
    'areas.apps.AreasConfig',
]

转到models.py中进行表结构的编译

class Areas(models.Model):
    name=models.CharField(max_length=50,verbose_name='location')
    pid=models.ForeignKey('self',on_delete=models.SET_NULL,related_name='addinfos',null=True)


    class Meta:
        db_table='areas'

    def __str__(self):
        return self.name

简单的几行代码,因为其实存储的时候地址只是单单一张表,而且每个地址都是由id,名字和一个foreign键组成,所以存储表结构并不难。这时候先迁移一次,创建这个地址表。
在创建前,我们之前用的表是没有设置UTF8中文可写的,所以这里可能不得不把数据库删了重新迁移,这是我的锅
在这里插入图片描述
重新创建以后不要忘记迁移和重新注册用户,以及之前的管理员用户。因为管理员用户也存在了之前的AbstractUser表中。
现在我们可以在网上找一个省市区表,然后将文件导入到mysql中。
sql的导入在很多地方有比我详细的介绍,我就不说了,我自己是用了骚操作,就是把sql文件中内容复制粘贴进表里,也是可以的
在这里插入图片描述
地址表的形式
在这里插入图片描述
复制粘贴后是这样的,你需要自己打最后一个回车就可以了,其他都自动导入
在这里插入图片描述
现在表就导入完毕了。
完成了这些以后,我们需要用serializer和view来实现一下查询
这里我稍微理一下思路。省我们需要在用户进入以后就列出来,方法为List然后列出省以后用户会查询特定的省,这就是retrieve动作了。特定省中由于外键和他所有的市链接,这里我们就把所有的市拿出来,然后用户又会选定特定的市。同样的和之前一样,这样我们在视图里面就需要实现Retrive方法,但是三级视图没有同时实现这两个办法的(当然两个动作都是由GET方法衍生出来的,所以在同一个视图不是很好将同一个方法变成不同的动作,所以就没有这种视图了),这里就要引入视图集的概念了。

视图集

视图集官方文档
视图集相对于视图来说,并没有指定method,比如get,post,put这些,但他指定了动作,比如List(),Retrieve()这些。这些方法我们之前也是在Mixin中看到过,但是视图集相对来说可以在一个函数中实现多种动作,所以这里我们使用了视图集。
其实还是比较好理解的,我们前端发送的应该都是get请求,但是这个get请求是会带参数访问的,而在逻辑上,全选和选单个的方法又是不一样的,所以这里就用了视图集来写。
视图集的url需要设置route,因为一个视图集可以做出好几个视图。

完成视图集

讲了这么多,现在就拿来用用吧
views

from django.shortcuts import render
from rest_framework.viewsets import ReadOnlyModelViewSet
from . import models
from . import serializers

# Create your views here.
class AreasViewSet(ReadOnlyModelViewSet):

    def get_queryset(self):
        if self.action=='list': #列出省
            return models.Areas.objects.filter(pid=None)
        else:   #选择省或市字段
            return models.Areas.objects.all()
    def get_serializer_class(self):
        if self.action=='list': #获得不带pid即addinfos的省
            return serializers.AreaInfoSerializer
        else:  #获得带pid的省或市,带addinfos列出下一级地区的id和name
            return serializers.NextAreasInfoSeria

serializers

from . import models
from rest_framework import serializers

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

class NextAreasInfoSeria(serializers.ModelSerializer):
	嵌套serializer查询外键具体内容,如果不添加,只输出外联表的外键id
    addinfos=AreaInfoSerializer(many=True,read_only=True)
    class Meta:
        model=models.Areas
        fields=('id','name','addinfos')

配置urls
模块内的urls

from .views import AreasViewSet
from rest_framework.routers import DefaultRouter


urlpatterns = [

]

router=DefaultRouter()
router.register('areas',AreasViewSet,base_name='areas')
urlpatterns +=router.urls

主urls

from django.conf.urls import url,include
from django.contrib import admin


urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'',include('user.urls')),
    url(r'areas/',include('areas.urls')),
]

为了解释上面的代码我们ctrl-B进入ReadonlyModelViewset视图的retrieve方法实现,可以看见这里我们只要使用了retrieve我们就已经可以获取到request需要的字段了,但是为什么我们在上面retrieve的实现中加上了object.all()这个方法呢?其实这个字段只是用来输出所有符合查询的字段,也就是其他都没法用,所以就直接这样输出了,其实在retrieve中早就已经通过serializer查询到了我们指定的字段了
在这里插入图片描述
先开启后端服务器,根据上面的url找到我们的后端中的视图
在这里插入图片描述
这里GET方法,因为并没有指定字段,现在我们查询特定字段,在url后传一个参数给后端
在这里插入图片描述
查询出来的样子是这样的,这是因为有一个迭代的serializer,查询官方文档中的serializer嵌套可以知道这是专门为了用来查询带关系的关联表处理方式,为了让关联数据也能显示出来。

drf-extensions

省市区的数据将会被多次访问,但是本身数据库中数据变化不大,这里就可以添加缓存来减少查询次数

安装

进入我们的虚拟环境键入

pip install drf-extensions

给请求添加缓存

装饰器

我们可以给请求加一个装饰器

    @cache_response(timeout=60*60, cache='default')
    def get(self, request, token):

timeout 缓存时间,单位秒
cache 缓存使用的Django缓存后端即选择的是redis中default数据库

继承

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

ListCacheResponseMixin
用于缓存返回列表数据的视图,与ListModelMixin扩展类配合使用,实际是为list方法添加了cache_response装饰器
RetrieveCacheResponseMixin
用于缓存返回单一数据的视图,与RetrieveModelMixin扩展类配合使用,实际是为retrieve方法添加了cache_response装饰器
CacheResponseMixin
为视图集同时补充List和Retrieve两种缓存,与ListModelMixin和RetrieveModelMixin一起配合使用。
我们只需要给我们这个带List和Retrieve两种动作的视图集添加扩展就可以了

from rest_framework_extensions.cache.mixins import CacheResponseMixin

# Create your views here.
class AreasViewSet(ReadOnlyModelViewSet,CacheResponseMixin):
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值