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

Django REST Framework中实现POST返回201后重定向的类视图

实现提交请假申请后返回201并重定向至待审批页面

嘿,我来帮你搞定这个需求!要实现员工提交请假申请后返回201状态码,同时跳转到/pending_for_approval页面并展示申请内容,分两种常见场景来处理,看你是用普通Django服务器渲染页面,还是前后端分离的API架构:

场景1:普通Django服务器端渲染(适合传统页面提交)

这种场景下,我们用Django的CreateView处理表单提交,并重定向到详情页面展示申请内容,同时满足状态码的要求。

步骤1:配置URL路由

先给提交申请和待审批页面配置URL:

# urls.py
from django.urls import path
from .views import LeaveApplyView, LeavePendingView

urlpatterns = [
    path('apply-leave/', LeaveApplyView.as_view(), name='apply_leave'),
    # 带申请ID的待审批页面,用来展示具体申请内容
    path('pending_for_approval/<int:pk>/', LeavePendingView.as_view(), name='pending_for_approval'),
]

步骤2:编写提交申请的类视图

重写CreateView的form_valid方法,保存申请后重定向到待审批页面,同时调整状态码(注:HTTP规范中POST后重定向建议用303状态码,但如果你坚持要返回201,也可以修改):

# views.py
from django.views.generic.edit import CreateView
from django.shortcuts import redirect
from django.urls import reverse
from .models import Leave
from .forms import LeaveApplyForm

class LeaveApplyView(CreateView):
    model = Leave
    form_class = LeaveApplyForm  # 你需要提前定义这个表单类

    def form_valid(self, form):
        # 保存用户提交的请假申请,自动关联当前登录员工
        self.object = form.save(commit=False)
        self.object.employee = self.request.user.employee
        self.object.save()
        
        # 生成待审批页面的跳转链接
        redirect_url = reverse('pending_for_approval', kwargs={'pk': self.object.pk})
        response = redirect(redirect_url)
        
        # 如果你需要严格返回201状态码(虽然不符合重定向的HTTP规范)
        # response.status_code = 201
        # 更合规的做法是用303状态码(POST请求后重定向,客户端会用GET请求目标页面)
        response.status_code = 303
        return response

步骤3:编写待审批页面的详情视图

用DetailView展示员工提交的申请内容,同时添加权限控制确保只有申请人能查看:

# views.py
from django.views.generic.detail import DetailView
from django.core.exceptions import PermissionDenied
from .models import Leave

class LeavePendingView(DetailView):
    model = Leave
    template_name = 'leave/pending_for_approval.html'  # 你的模板文件路径
    context_object_name = 'leave_application'  # 模板中用来调用申请对象的变量名

    def get_object(self, queryset=None):
        obj = super().get_object(queryset)
        # 验证当前用户是申请的提交人
        if obj.employee != self.request.user.employee:
            raise PermissionDenied("你无权查看该申请")
        return obj

步骤4:编写待审批页面模板

在pending_for_approval.html中展示申请内容:

<!-- templates/leave/pending_for_approval.html -->
<h1>申请已提交,等待审批</h1>
<div class="application-details">
    <p><strong>申请人:</strong>{{ leave_application.employee.name }}</p>
    <p><strong>请假类型:</strong>{{ leave_application.leave_type }}</p>
    <p><strong>开始日期:</strong>{{ leave_application.start_date|date:"Y-m-d" }}</p>
    <p><strong>结束日期:</strong>{{ leave_application.end_date|date:"Y-m-d" }}</p>
    <p><strong>申请理由:</strong>{{ leave_application.reason }}</p>
</div>

场景2:Django REST Framework API(前后端分离)

如果是前后端分离的架构,API返回201状态码的同时,告诉前端要跳转的页面地址,有两种方式:

方式1:通过响应头返回跳转地址

在CreateAPIView中添加Location响应头,前端可以读取该头进行跳转:

# views.py
from rest_framework.generics import CreateAPIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from django.urls import reverse
from .models import Leave
from .serializers import LeaveSerializer

class LeaveApplyAPI(CreateAPIView):
    queryset = Leave.objects.all()
    serializer_class = LeaveSerializer
    permission_classes = [IsAuthenticated]  # 只允许登录用户提交

    def perform_create(self, serializer):
        # 自动关联当前登录员工
        serializer.save(employee=self.request.user.employee)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        
        # 生成待审批页面的绝对URL
        pending_url = reverse('pending_for_approval', kwargs={'pk': serializer.instance.pk})
        absolute_url = request.build_absolute_uri(pending_url)
        
        # 添加Location响应头
        headers['Location'] = absolute_url
        
        # 返回201状态码和申请数据,同时带跳转地址头
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

方式2:在响应体中返回跳转地址

如果前端更倾向于从响应体获取跳转地址,可以在返回的JSON中添加redirect_url字段:

def create(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    self.perform_create(serializer)
    headers = self.get_success_headers(serializer.data)
    
    pending_url = reverse('pending_for_approval', kwargs={'pk': serializer.instance.pk})
    absolute_url = request.build_absolute_uri(pending_url)
    
    # 把跳转地址加入响应数据
    response_data = serializer.data
    response_data['redirect_url'] = absolute_url
    
    return Response(response_data, status=status.HTTP_201_CREATED, headers=headers)

之后前端可以根据redirect_url字段跳转到待审批页面,页面可以通过API获取申请详情并展示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:11:42