You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django DRF如何创建免认证公共端点实现地图数据可视化

问题原因

现有代码两处配置导致公共访问失败:

  • MarkerViewSet全局配置IsAuthenticated权限,所有接口(包括GET查询)强制要求携带有效Token认证
  • get_queryset方法默认按user=self.request.user过滤结果,未登录状态下匿名用户无关联数据,就算放开权限也查不到任何标记,且登录用户也仅能查到自己创建的内容,无法获取全量标记用于地图展示。
改造方案

最小代码改动实现需求:保留原有认证用户的创建、编辑、上传图片等操作逻辑不变,仅放开列表查询接口的GET请求权限,且该接口返回全量用户创建的标记。

第一步:修正导入与视图逻辑

修改markers/views.py,首先补充权限类导入,再调整视图集的权限、查询集逻辑,同时修复原有代码的拼写错误:

# 补充导入AllowAny权限类
from rest_framework.permissions import IsAuthenticated, AllowAny

# 其他原有导入保持不变...

class MarkerViewSet(viewsets.ModelViewSet):
    """Marker view set."""
    bbox_filter_field = 'location'
    filter_backends = (filters.InBBoxFilter,)
    queryset = Marker.objects.all()
    serializer_class = MarkerSerializer
    authentication_classes = [TokenAuthentication]
    # 删除全局permission_classes配置,改用动态权限判断

    def get_permissions(self):
        # 列表查询动作(GET /api/markers/markers/)允许所有未认证用户访问
        if self.action == 'list':
            return [AllowAny()]
        # 其余动作(创建、修改、删除、上传图片等)全部要求认证
        return [IsAuthenticated()]

    def get_queryset(self):
        # 公共列表接口返回全量标记,保留原有bbox过滤能力适配地图视野查询
        if self.action == 'list':
            return self.queryset.all().order_by('-id')
        # 认证场景下仅返回当前用户自己的标记,避免越权操作他人数据
        return self.queryset.filter(user=self.request.user).order_by('-id')

    def get_serializer_class(self):
        """Return the serializer class for request"""
        if self.action == 'list':
            return serializers.MarkerSerializer
        elif self.action == 'upload_image':
            return serializers.MarkerImageSerializer
        return self.serializer_class

    def perform_create(self, serializer):
        """Create a new marker"""
        serializer.save(user=self.request.user)

    @action(methods=['POST'], detail=True, url_path='upload_image')
    def upload_image(self, request, pk=None):
        marker = self.get_object()
        serializer = self.get_serializer(marker, data=request.data)
        if serializer.is_valid():
            # 修复原代码Reponse拼写错误为Response
            return Response(serializer.data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


class MarkersMapView(TemplateView):
    """Markers map view."""
    template_name = 'map.html'

第二步:验证逻辑

路由无需任何修改,改造后接口逻辑符合预期:

  • 未认证用户发送GET请求到/api/markers/markers/:可正常获取全量标记数据,支持原有的BBox范围过滤,直接供地图页面渲染使用
  • 未认证用户发送POST/PUT/DELETE等写请求到标记相关接口:返回401未认证,无操作权限
  • 已认证用户的创建标记、上传图片、编辑/删除自有标记等功能逻辑完全不变,且无法操作其他用户创建的标记,无越权风险
  • 原/api/markers/map/模板页面可正常访问,页面内请求标记接口不会再被权限拦截。

内容的提问来源于stack exchange,提问作者SilveTCL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:36:27