Django 使用models.Manager扩展查询的方法

先来扩展一下使用.all()查询时,通过传入自定义参数返回不同的数据集

1、在模型中使用models.Manager

# 自定义扩展.all()方法
class MiddlewareRegionSplitManager(models.Manager):
    def all(self, user=None):
        if user:
        	# 当没有 region_split 并且 group_id 为1时返回所有数据 否则只返回与user.region_split所匹配的数据
            if not user.region_split and user.group_id == 1:
                return super().all()
            else:
                return super().all().filter(region_split=user.region_split)
        # 如果没有传入user参数 返回所有数据
        return super().all()

# 当所有模型都包含这些字段时,这里可以定义一个基本模型,让其他模型都继承与它
class BaseModel(models.Model):
    sort = models.IntegerField(default=1, null=True, blank=True, verbose_name='排序')
    content = models.TextField(default='', null=True, blank=True, verbose_name='描述')
    sort_time = models.DateTimeField(auto_now_add=True, verbose_name='排序时间')
    created = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    region_split = models.IntegerField(null=True, blank=True, verbose_name='所属区域')
    # 定义使用的models.Manager
    objects = MiddlewareRegionSplitManager()

    class Meta:
        abstract = True

# 定义一个系统字典模型
class ConfDict(SoftDeleteModel, BaseModel):
    dict_title = models.CharField(max_length=255, verbose_name='字典标题')
    dict_key = models.IntegerField(default=0, verbose_name='字典键值')
    dict_type = models.IntegerField(default=0, verbose_name='字典类型')

    class Meta:
        db_table = 'A_ConfDict_Table'
        verbose_name = '系统字典表'
        verbose_name_plural = verbose_name
        # unique_together = (('dict_title', 'region_split'), ) 设置联合唯一

2、在视图中使用

class CongDictViewset(ModelViewSet):
    '''
    修改局部数据
    create:  创建系统字典
    retrieve:  检索某个系统字典
    update:  更新系统字典
    destroy:  删除系统字典
    list:  获取系统字典列表
    '''
    queryset = ConfDict.objects.all().order_by('-updated')
    serializer_class = ConfDictSerializer
    authentication_classes = [JWTAuthentication, ]
    permission_classes = []
    # 频率验证
    throttle_classes = [VisitThrottle]
    # drf 过滤&搜索&排序
    filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter,)
    # 搜索
    search_fields = ('dict_title', 'content',)
    # 过滤
    filter_fields = ('dict_type',)
    # 排序
    ordering_fields = ('updated', 'sort_time', 'created',)
    pagination_class = Pagination

    def get_permissions(self):
    	# 指定get查询时 不需要权限
        if self.action == 'list':
            return []
        else:
            return [BasePermission()]
    
    def get_queryset(self):
        if self.request.auth:
        	# 当用户登录了 得到用户 user 参数 传入 .all()方法 来返回不同的结果
            return ConfDict.objects.all(user=self.request.user).order_by('-updated')
        # 当没有登录时正常返回
        return ConfDict.objects.all().order_by('-updated')

3、重新定义自己的方法

# 修改定义的 MiddlewareRegionSplitManager 类 如下示
class MiddlewareRegionSplitManager(models.Manager):
	def region(self, user=None):
        queryset = super().get_queryset()
        if user:
        	if not user.region_split and user.group_id == 1:
                pass
            else:
                queryset = queryset.filter(region_split=user.region_split)
        return queryset

4、在试图中使用

将 get_queryset 方法修改如下示

def get_queryset(self):
	if self.request.auth:
		# 当用户登录了 得到用户 user 参数 传入 .all()方法 来返回不同的结果
	    return ConfDict.objects.all().region(user=user).order_by('-updated')
	# 当没有登录时正常返回
	return ConfDict.objects.all().order_by('-updated')
上一篇:VS2019 开发Django(六)------Admin中图片上传


下一篇:TypeError: fit() got an unexpected keyword argument 'nb_epoch'