Django项目(五)收货地址的实现

一.省市区地址查询

首先分析数据模型类的设计

设计成3张表肯定是不合理的,由于省,市,区具有共性,我们将其设置成一张表

id,name,parent

省的parent设置为null,市的parent设置为省的id,区(县)的parent设置为市的id

class Area(models.Model):
    """
    行政区划
    """
    name = models.CharField(max_length=20, verbose_name='名称')
    parent = models.ForeignKey('self', on_delete=models.SET_NULL, related_name='area_set', null=True, blank=True,
                               verbose_name='上级行政区划')

    class Meta:
        db_table = 'tb_areas'
        verbose_name = '行政区划'
        verbose_name_plural = '行政区划'

    def __str__(self):
        return self.name

完成数据迁移操作

python manage.py makemigrations
python manage.py migrate

向数据表中添加数据

1.直接复制.sql文件中的全部内容,粘贴到数据库中(终端)

2.在终端中使用source方式导入(需要注意.sql文件的路径) 

3.脚本导入创建一个.sh文件(假设创建abc.sh)

#!/usr/bin/env bash

mysql -h127.0.0.1 -uname -ppassword databasename < ./file.sql

修改文件执行权限

chmod +x abc.sh

然后执行如下命令导入数据

./abc.sh

这样数据就全部添加到数据表中了

刷新页面时,获得所有省信息

选择省获取所有市信息

选择市获取所有区县信息

1)请求省份数据

请求方式 GET /areas/infos/

返回数据

返回值 类型 是否必传 说明
id int 省份id
name str 省份名称

2)请求城市或区县数据

请求方式 GET/areas/infos/(?P<pk>\d+)/

请求参数

参数 类型 是否必传 说明
pk int 上级区划id(省份id用于获取城市数据,或城市id用于获取区县数据)

返回数据

返回值 类型 是否必传 说明
id int 上级区划id(省份id或城市id)
name str 上级区划的名称
subs list[] 下属所有区划信息

 可以知道以上都是get方法,我们可以使用ReadOnlyModelViewSet

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

    # serializer_class = AreaSerializer
    def get_serializer_class(self):
        if self.action == 'list':
            return AreaSerializer
        else:
            return SubAreaSerializer

代码分析:

由于省和市区的查询结果集是不相同的,所以我们需要重写get_queryset来重新定义结果集

if self.action == 'list':
            return Area.objects.filter(parent=None)

这个很容易能够知道,查询的结果集就是数据表中parent=None的数据

else:
            return Area.objects.all()

我们要知道市区是怎么实现的

 ReadOnlyModelViewSet继承了RetrieveModelMixin,

 RetrieveModelMixin有retrieve函数,get_object中实现了用PK值返回单个对象

所以直接 return Area.objects.all()就可以了

序列化器

class AreaSerializer(serializers.ModelSerializer):
    """
    行政区划信息序列化器
    """

    class Meta:
        model = Area
        fields = ['id', 'name', 'parent_id']

class SubAreaSerializer(serializers.ModelSerializer):
    area_set = AreaSerializer(many=True,read_only=True)
    class Meta:
        model = Area
        fields = ['area_set']

在点击省获取到所有市信息,我们只能得到省的id,但省的id是这个省所有市的parent_id,

所以,我们可以用1对多的方式来获得数据

我们可以给定一个字段等于序列化器,得到的就是所有市的信息了

从市得到区的过程同上,就不需要额外写了

改写前端代码

二.使用缓存

省市区的数据是经常被用户查询使用的,而且数据基本不变化,所以我们可以将省市区数据进行缓存处理,减少数据库的查询次数。

安装:pip install drf-extensions

为省市区视图添加缓存(添加CacheResponseMixin)

from rest_framework_extensions.cache.mixins import CacheResponseMixin
# Create your views here.

class AreaViewSet(CacheResponseMixin,ReadOnlyModelViewSet):
    """
    行政区划信息
    list: GET /areas/
    retrieve: GET /areas/(?P<pk>\d+)/
    """

在setting中添加配置

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

三.户地址管理

1.增加地址

2.地址列表

3.删除地址

4.修改信息

5.设置默认地址

同讲义中内容一模一样

2点需要注意的地方....

1.创建序列化器AddressSerializer时 exclude 中is_delete需要删除

2.地址列表中前端代码需要写在钩子函数中(因为页面一刷新就需要显示)

我他么写完了需要提交的时候要重新登录什么都没了........

算了算了,生气伤身......

等我心情好了换种继承类写一次......

最后结果:

猜你喜欢

转载自blog.csdn.net/Spencer_q/article/details/82084603