如何在DRF CreateAPIView中通过slug关联外键创建评论
我来帮你搞定这个需求!要实现用Post的slug代替ID来关联创建评论,其实有两种很实用的方案,我给你详细拆解一下:
方案1:用DRF原生的SlugRelatedField处理(推荐)
这种方式最简洁,直接修改序列化器,把原来关联Post ID的字段换成关联slug的字段就行:
from rest_framework import serializers from .models import Comments, Posts class CommentCreateSerializer(serializers.ModelSerializer): # 替换原来的post字段,指定用slug匹配Post post = serializers.SlugRelatedField( queryset=Posts.objects.all(), slug_field='slug' # 这里填你Post模型里的slug字段名 ) class Meta: model = Comments fields = ['content', 'post']
改完之后,前端发起POST请求时,直接传{"content": "你的评论内容", "post": "目标帖子的slug值"}就可以了。DRF会自动根据slug找到对应的Post对象,帮你关联到新创建的评论上,而且如果slug不存在,序列化器会自动返回验证错误,非常省心。
方案2:重写视图的perform_create方法(更灵活)
如果你不想修改序列化器,或者需要在创建评论前做一些额外逻辑(比如校验用户是否有权限评论这个帖子),可以用这种方式:
首先保持序列化器不变,但要把post字段设为只读(或者直接从fields里去掉):
class CommentCreateSerializer(serializers.ModelSerializer): class Meta: model = Comments fields = ['content'] # 或者保留post字段但设为只读: # read_only_fields = ['post']
然后修改你的View,重写perform_create方法,手动通过slug找到Post再创建评论:
from rest_framework.generics import CreateAPIView from rest_framework.permissions import IsAuthenticated from django.shortcuts import get_object_or_404 from .models import Comments, Posts from .serializers import CommentCreateSerializer class CommentCreateView(CreateAPIView): permission_classes = [IsAuthenticated] queryset = Comments.objects.all() serializer_class = CommentCreateSerializer def perform_create(self, serializer): # 从请求数据里拿到slug post_slug = self.request.data.get('post_slug') # 用get_object_or_404避免slug不存在时抛500错误,返回404更合理 target_post = get_object_or_404(Posts, slug=post_slug) # 把找到的Post对象传给序列化器保存 serializer.save(post=target_post)
这时候前端的POST请求要改成传{"content": "你的评论内容", "post_slug": "目标帖子的slug值"}。
小提示
如果你的Post模型里的slug不是唯一的,记得先给slug字段加上unique=True约束,不然查询的时候可能会返回多个结果导致报错哦:
class Posts(models.Model): title = models.CharField(max_length=512, null=True) slug = models.CharField(max_length=512, null=True, unique=True) # 加上唯一约束
内容的提问来源于stack exchange,提问作者Howard Scott
相关产品推荐
相关产品推荐

