"/>
侧边栏壁纸
博主头像
PySuper 博主等级

千里之行,始于足下

  • 累计撰写 218 篇文章
  • 累计创建 15 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录
Web

Django--分页器、过滤器、权限类

PySuper
2024-10-19 / 0 评论 / 1 点赞 / 13 阅读 / 0 字
温馨提示:
所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

分页器

class CorePagination(PageNumberPagination):
    """分页设置"""

    page_size = 10
    page_size_query_param = "size"
    max_page_size = 100


class LargePagination(PageNumberPagination):
    """自定义分页类,支持动态页面大小"""

    # 定义前端分页参数名称
    page_query_params = "current"

    # 允许通过 URL 查询参数 'size' 动态设置页面大小
    page_size = 10
    page_size_query_param = "size"
    max_page_size = 100

    def get_paginated_response(self, data):
        """返回分页后的响应,包含自定义的响应格式"""
        # 使用三元表达式简化 code 和 msg 的赋值逻辑
        code = 200 if data else 404
        msg = "请求成功" if data else "数据请求失败"

        # TODO: 自定义ViewSet分页响应
        return Response(
            OrderedDict(
                [
                    ("code", code),
                    ("msg", msg),
                    (
                        "data",
                        OrderedDict(
                            [
                                ("records", data),
                                ("current", self.page.number),
                                ("size", self.page_size),
                                ("total", self.page.paginator.count),
                            ]
                        ),
                    ),
                ]
            )
        )

    # 动态获取前端分页参数名称
    def get_page_query_param(self):
        """
        获取 URL 上的 'current' 参数,如果没有 'current' 参数,返回 'current' 作为默认值
        :return:
        """
        return self.page_query_params or "current"

过滤器

class QueryFilter(django_filters.rest_framework.FilterSet):
    """
    自定义查询过滤器,增加常用功能
    """

    del_flag = django_filters.rest_framework.BooleanFilter(field_name="del_flag", lookup_expr="exact", required=False)
    create_date = django_filters.rest_framework.DateFromToRangeFilter(field_name="create_date", label="创建日期范围")
    update_date = django_filters.rest_framework.DateFromToRangeFilter(field_name="update_date", label="更新日期范围")
    search = django_filters.rest_framework.CharFilter(method="filter_by_all_fields", label="模糊搜索")

    class Meta:
        model = BaseEntity
        fields = ["del_flag", "create_date", "update_date"]  # 定义需要查询的字段

    def filter_queryset(self, queryset):
        """重写 filter_queryset 方法,自动过滤 del_flag=True 的数据"""
        queryset = queryset.filter(del_flag=False)
        queryset = super().filter_queryset(queryset)
        return queryset

    def filter_by_all_fields(self, queryset, name, value):
        """模糊搜索,搜索所有文本字段"""
        for field in self.Meta.model._meta.fields:
            if isinstance(field, (CharField, TextField)):
                queryset = queryset.filter(**{f"{field.name}__icontains": value})
        return queryset

权限类

class RbacPermission(BasePermission):
    """
    自定义权限类,基于用户角色权限控制。
    """

    @classmethod
    def get_permission_from_role(cls, request) -> Optional[List[str]]:
        """
        获取用户角色的权限,去重
        :param request: 请求对象
        :return: 权限列表或 None
        """
        if not request.user.is_authenticated:
            return None
        return list(request.user.roles.values_list("perms__method", flat=True).distinct())

    def has_permission(self, request, view) -> bool:
        """
        权限校验逻辑
        :param request: 请求对象
        :param view: 视图对象
        :return: 是否有权限
        """
        perms = self.get_permission_from_role(request) or []

        if "admin" in perms:
            return True  # 管理员直接拥有所有权限

        # 如果视图没有权限映射,直接返回有权限
        if not hasattr(view, "perms_map"):
            return True

        # 获取请求方法
        method = request.method.lower()

        # 校验权限
        return any(
            (method == method_key or method_key == "*") and alias in perms
            for perm_map in view.perms_map
            for method_key, alias in perm_map.items()
        )




class ObjPermission(BasePermission):
    """密码管理对象级权限控制"""

    def has_object_permission(self, request, view, obj) -> bool:
        """
        检查用户是否有权限访问特定对象
        :param request: 请求对象
        :param view: 视图对象
        :param obj: 要检查的对象
        :return: 是否有权限
        """
        # 获取用户角色的权限
        user_perms = RbacPermission.get_permission_from_role(request) or []

        # 管理员拥有所有权限
        if "admin" in user_perms:
            return True

        # 检查用户是否有权限访问特定对象
        return request.user.id == obj.uid_id

1
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区