在Django+DRF+Vue.js+Djoser中设置表单提交的created_by字段
最佳实现方案
要在后端自动设置created_by为当前提交请求的登录用户,核心是利用Django REST Framework的认证机制获取当前用户,再在序列化保存时注入该用户,具体步骤如下:
1. 配置后端Token认证
首先在Django项目的settings.py中配置Token认证,让后端能识别前端携带的Token并关联到用户:
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.TokenAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', # 限制仅登录用户可提交 ] }
2. 前端请求携带Token
前端发送POST请求时,需将localStorage中的Token放入请求头,以Axios为例:
const token = localStorage.getItem('token'); axios.post('/api/projects/', { project_title: this.project_title, project_description: this.project_description, interest_category: this.interest_category, }, { headers: { 'Authorization': `Token ${token}` // 携带Token完成用户认证 } }) .then(res => { // 处理成功逻辑 }) .catch(err => { // 处理错误逻辑 });
3. 修改序列化器,标记created_by为只读
created_by由后端自动设置,无需前端传递,因此在序列化器中将其设为只读字段,同时修正interest_category的序列化规则(原StringRelatedField为只读,无法接收前端值):
from rest_framework import serializers from .models import Project class ProjectsSerializer(serializers.ModelSerializer): interest_category = serializers.PrimaryKeyRelatedField(queryset=InterestCategory.objects.all()) # 替换为你的分类模型,前端传ID即可 created_by = serializers.StringRelatedField(read_only=True) # 设为只读,返回时展示用户信息 class Meta: model = Project fields = ( 'project_title', 'project_description', 'interest_category', 'created_by', 'created_at', 'updated_at', )
4. 修正视图逻辑,注入当前用户
原视图继承RetrieveAPIView不适用于列表查询和创建操作,推荐改用ListCreateAPIView,并通过重写方法注入用户:
方式一:使用ListCreateAPIView(推荐)
from rest_framework import generics from .models import Project from .serializers import ProjectsSerializer from rest_framework.permissions import IsAuthenticated class ProjectView(generics.ListCreateAPIView): queryset = Project.objects.order_by('-created_at') serializer_class = ProjectsSerializer permission_classes = [IsAuthenticated] # 重写创建逻辑,自动注入当前用户 def perform_create(self, serializer): serializer.save(created_by=self.request.user)
方式二:修正原POST方法
若坚持原视图结构,需修正序列化器实例化错误并注入用户:
from rest_framework import generics from rest_framework.response import Response from rest_framework import status from .models import Project from .serializers import ProjectsSerializer class ProjectView(generics.RetrieveAPIView): queryset = Project.objects.order_by('-created_at') def get(self, request): queryset = self.get_queryset() serializer = ProjectsSerializer(queryset, many=True) return Response(serializer.data) def post(self, request): serializer = ProjectsSerializer(data=request.data) if serializer.is_valid(): serializer.save(created_by=request.user) # 注入当前登录用户 return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
关键补充
确保Project模型中created_by字段定义正确:
from django.db import models from django.contrib.auth.models import User class Project(models.Model): project_title = models.CharField(max_length=255) project_description = models.TextField() interest_category = models.ForeignKey(InterestCategory, on_delete=models.CASCADE) created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='projects') created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True)
内容的提问来源于stack exchange,提问作者ckcAdmin
相关产品推荐
相关产品推荐

