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

DRF中CreateAPIView重写perform_create传参watchlist的疑问

DRF中ReviewCreate视图的运行逻辑解惑

问题描述

用户提供的视图代码:

class ReviewCreate(generics.CreateAPIView):
    # queryset=Review.objects.all()
    serializer_class=ReviewSerializer

    def perform_create(self, serializer):
        pk=self.kwargs.get('pk')
        # print(pk)
        watchlist=WatchList.objects.get(pk=pk)
        serializer.save(watchlist=watchlist)    
        print("1")

同时查看了DRF CreateModelMixin的源码:

class CreateModelMixin:
    """
    Create a model instance.
    """
    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)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save()

    def get_success_headers(self, data):
        try:
            return {'Location': str(data[api_settings.URL_FIELD_NAME])}
        except (TypeError, KeyError):
            return {}

用户有三个核心疑问:

  • 为何要在serializer.save(watchlist=watchlist)中传入watchlist=watchlist?
  • 父类perform_create已调用serializer.save(),为何自定义的perform_create还要再次调用并传参?
  • Review模型还有其他字段,仅传watchlist为何能创建数据?

解答

1. 传入watchlist=watchlist的原因

Review模型和WatchList模型应该是外键关联的(比如Review有一个watchlist外键字段指向WatchList)。这个字段的值不能从前端提交的request.data里获取——它是通过URL中的pk参数确定对应WatchList实例的,不属于用户输入的数据。

DRF序列化器调用save()时,会把传入的额外关键字参数直接赋值给模型实例的对应字段。这样就能自动给新创建的Review绑定指定的WatchList,既避免了用户手动提交外键可能带来的错误,也简化了前端的请求逻辑。

2. 重写perform_create后仍需调用serializer.save()的原因

父类的perform_create只是一个默认实现,当你重写这个方法时,父类的默认逻辑会被完全覆盖,不会再执行。所以必须在自定义的perform_create里手动调用serializer.save(),同时补充上请求体里没有的参数——这不是重复调用,而是替换了父类的默认调用行为。

3. 仅传watchlist就能创建数据的原因

并非只传了watchlist,实际是两种数据来源合并后创建的实例:

  • 序列化器已经通过self.get_serializer(data=request.data)加载了前端提交的其他字段数据,只要这些字段通过了序列化器的验证,就会被用来创建实例。
  • Review模型的其他字段要么是允许为空(null=True/blank=True),要么有默认值,即使前端没提交也能满足模型的创建要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:43:14