Django开发

Django+DRF+PostgreSQL+Redis+Celery 后端开发日志

组件介绍

Django

python开发常用的框架有很多,这里推荐两种

  1. Flask:用于快速开发,比如接受其他平台发送的请求
  2. Django:用于大型项目的开发,有较为完整的功能,如分页、权限等

本文选择的版本是长期稳定更新的4.2

DRF

这是一个用于前后端分离的组件

drf官网

目前没有中文文档,并且社区热度一般,如果没有web开发基础建议去学Flask

本文选择的是较新版本3.14.0

PostgreSQL

一个分布式开源的关系型数据库,相较于MySQL在django中支持的字段会更丰富,能够存储Json、list等数据
本文选择的是Docker下的最新版

docker下安装PostgreSQL

Redis

非关系型数据库,用于缓存及Celery中的 BROKER配置
windows下安装最新版即可

Celery

用于异步任务、定时任务的组件,本文涉及异步爬虫和开放平台AP调用所有选型了Python作为开发语言
本文选用最新版 5.3.6

开发思路

就像Java 的Spring Boot框架的软件设计模式是MVC(Model View Controller),
在我实际的开发过程中 我也总结出了一种类似的模式 MSFVU(Model Serializer Filter ViewSet Url),这个过程可以大致的表述从数据在前后端的流动过程。

Model

即模型,笼统的说就是一个抽象的类,它拥有属性、方法,在实际开发中常常会和持久化联系密切。

class Category(models.Model):
    id = models.AutoField(verbose_name='类目id', primary_key=True)
    categoryQuery = models.CharField(max_length=50, verbose_name='查询类目')
    categoryMatching = models.CharField(max_length=50, verbose_name='匹配类目')

    class Meta:
        db_table = 'category'
        verbose_name = '类目表'
        verbose_name_plural = verbose_name
# 特别情况-父子关系
class Account(MPTTModel):
    account_type_choices = (
        (0, '总账户'),
        (1, '子账户'),
    )
    id = models.AutoField(primary_key=True)
    account_type = models.CharField(choices=account_type_choices, max_length=50,
                                    verbose_name='类型(总账户/子账户)', db_column='account_type')
    account_name = models.CharField(max_length=128, verbose_name='账户名称', db_column='account_name',
                                        null=True, blank=True)
    account_password = models.CharField(max_length=128, verbose_name='账户密码', db_column='account_password')
    account_status = models.BooleanField(default=True, verbose_name="账户状态(启用/禁用)", db_column='account_status')
    parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True,
                            related_name='child_accounts', verbose_name='所属总账户', db_column='parent')
    objects = TreeQuerySet.as_manager()
    class MPTTMeta:
        order_insertion_by = ['id']
    class Meta:
        db_table = 'account'
        verbose_name = '账户表'
        verbose_name_plural = verbose_name

Serializer

序列化器,就是能将机器编码和人类语言相互转换的中间件,可以完成Java中DTO、VO的功能。这里需要掌握的是什么是序列化,什么是反序列化。

将对象的状态转换为适合存储、传输或展现(如JSON、XML或二进制格式)的数据格式,这个过程被称为序列化。反之,从这样的数据格式还原成对象状态的过程称为反序列化。

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = '__all__'
# 特别情况-父子关系
class AccountSerializer(serializers.ModelSerializer):
    account_type_choices = (
        (0, '总账户'),
        (1, '子账户'),
    )
    account_type = serializers.ChoiceField(choices=account_type_choices, label='类型(总账户/子账户)')
    children = serializers.SerializerMethodField()
    def get_children(self, obj):
        return self.__class__(obj.get_children(), many=True).data
    class Meta:
        model = Account
        exclude = ['token']

Filter

过滤器,django自带的也有,但是功能不够丰富,drf官方推荐引入组件django-filter,本文选用的版本是23.5,主要是实现时间的区间查询、模糊查询等。

class CategoryFilter(filters.FilterSet):
    class Meta:
        model = Category
        fields = '__all__'
# 模糊查询
class AccountFilter(filters.FilterSet):
    account_username = filters.CharFilter(lookup_expr='icontains')
    # 如果使用特殊字段类型的如Array、JSON等记得要配置,不然报错
    class Meta:
        model = Account
        fields = '__all__'
        filter_overrides = {
            JSONField: {
                'filter_class': django_filters.CharFilter,
                'extra': lambda f: {
                    'lookup_expr': 'icontains',
                },
            },
        }
# 区间查询
class DjangoCeleryResultsTaskresultFilter(filters.FilterSet):
    startTime = django_filters.DateTimeFilter(field_name='date_created__date', lookup_expr='gte')
    endTime = django_filters.DateTimeFilter(field_name='date_created__date', lookup_expr='lte')
    class Meta:
        model = DjangoCeleryResultsTaskresult
        fields = '__all__'  # 或者指定具体的字段列表

ViewSet

视图集,drf的view层有三种写法,基于方法的视图、基于类的视图、基于视图集。在实际开发中我会以第三种为主,另外两种作为补充。为了更好的集成drf-yasg 我继承并重写了ModelViewSet这个我的utils包下有。

class CategoryViewSet(CustomModelViewSet):
    queryset = Category.objects.all()
    serializer_class = CategorySerializer
    filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
    filterset_class = CategoryFilter

Url

用于向前端暴露接口的,可以分App写,然后在setting同级的url中组合。
如果使用ViewSet则需要用

router = DefaultRouter()
router.register(r'<路径>', <ViewSet>)
core_urls = router.urls

例如:

router.register(r'category', CategoryViewSet)

本文持续更新

  • 19
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值