Django REST Framework列表按用户筛选及权限控制实现问询
Django REST Framework Listing 权限与筛选实现方案
先补全基础模型(假设你的模型结构如下,若有差异可调整)
from django.db import models from django.contrib.auth import get_user_model User = get_user_model() class Listing(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='listings') title = models.CharField(max_length=255) description = models.TextField() is_listed = models.BooleanField(default=True) # 默认上架 created_at = models.DateTimeField(auto_now_add=True)
1. 核心:修复可见性问题 + 实现多维度筛选
重写视图的get_queryset方法,精准控制不同用户能看到的内容,同时处理user_id和status筛选参数:
from rest_framework import viewsets from rest_framework.permissions import IsAuthenticatedOrReadOnly from .models import Listing from .serializers import ListingSerializer from .permissions import IsOwnerOrReadOnly class ListingViewSet(viewsets.ModelViewSet): serializer_class = ListingSerializer permission_classes = [IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly] def get_queryset(self): queryset = Listing.objects.all() # 处理user_id筛选:有参数则过滤,无则返回全部基础数据集 user_id = self.request.query_params.get('user_id') if user_id: queryset = queryset.filter(user_id=user_id) # 可见性规则:自己的Listing全可见,他人仅可见上架的 if self.request.user.is_authenticated: own_listings = queryset.filter(user=self.request.user) other_listings = queryset.filter(user__ne=self.request.user, is_listed=True) queryset = own_listings | other_listings else: # 未登录用户只能看所有上架Listing queryset = queryset.filter(is_listed=True) # 处理status筛选:listed(上架)/unlisted(下架)/all(全部) status = self.request.query_params.get('status') if status == 'listed': queryset = queryset.filter(is_listed=True) elif status == 'unlisted': # 仅所有者能查看自己的下架内容 if self.request.user.is_authenticated: queryset = queryset.filter(user=self.request.user, is_listed=False) else: queryset = Listing.objects.none() return queryset.distinct()
2. 自定义权限:仅所有者可编辑/删除
新建permissions.py文件,添加权限类:
from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): def has_object_permission(self, request, view, obj): # GET/HEAD/OPTIONS 请求允许所有用户访问 if request.method in permissions.SAFE_METHODS: return True # 写操作仅允许Listing所有者执行 return obj.user == request.user
3. 序列化器:自动关联用户 + 控制字段权限
from rest_framework import serializers from .models import Listing class ListingSerializer(serializers.ModelSerializer): class Meta: model = Listing fields = ['id', 'user', 'title', 'description', 'is_listed', 'created_at'] read_only_fields = ['user'] # 禁止前端修改用户字段,由后端自动填充 def create(self, validated_data): # 创建时自动绑定当前登录用户 validated_data['user'] = self.context['request'].user return super().create(validated_data)
关键逻辑说明
- 未登录用户:仅能查看所有公开上架的Listing,无法创建/修改
- 登录用户:
- 查看自己的所有Listing(上架/下架)
- 查看其他用户仅上架的Listing
- 仅能创建、编辑、删除自己的Listing
- 通过
user_id参数筛选特定用户的公开Listing - 通过
status参数筛选自己的上架/下架/全部内容
内容的提问来源于stack exchange,提问作者Simeon Todorov
相关产品推荐
相关产品推荐

