Django休息框架: Correct way to override perform_create in ModelViewSet?

标签 django django-rest-framework

我现在已经解决了这个问题,因此请向下滚动到问题底部以查看解决方案

在 Django Rest Framework 中,当在一个模型上发生插入时,我想在其他模型上进行更新/插入。

我正在使用 ModelViewSet 并尝试覆盖 perform_create 方法,但原始插入只是被吞掉,没有发生更新,也没有看到错误.

我尝试过这样做

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

但是虽然没有抛出错误,但也没有发生更新。

希望有一个覆盖perform_create的示例,以便原始插入仍然发生,但有空间同时进行其他更新/插入。

我正在使用 DRF 3.5.3 。


编辑:这是完整的 ModelViewSet 代码。

class AttemptViewSet(viewsets.ModelViewSet):
    '''
    API endpoint that allows Attempt to be CRUDed.
    '''

    queryset = Attempt.objects.all()
    serializer_class = AttemptSerializer
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def perform_create(self, serializer):
        import pdb;pdb.set_trace()
        serializer.save()

    def initial(self, request, *args, **kwargs):
        '''
        Temporary diagnostic code which should
        be removed once it's possible to update
        an Attempt
        '''

        import os
        import json

        # 'request_auth': request.auth,
        log_data = {
            'user': request.user.pk,

            'remote_address': request.META['REMOTE_ADDR'],

            'request_method': request.method,
            'request_path': request.get_full_path(),
            'request_body': request.data ,
            'request_query_params': request.query_params
        }
        if not os.path.exists('/tmp/spellsplashlog'):
            os.makedirs('/tmp/spellsplashlog')

        with open('/tmp/spellsplashlog/logging.json', 'w') as f:
            json.dump(log_data, f, sort_keys=True, indent=4)

        viewsets.ModelViewSet.initial(self, request, *args, **kwargs)

...这是序列化器...

class AttemptSerializer(serializers.ModelSerializer):
    class Meta:
        model = Attempt
        fields = '__all__'

...这是模型...

class Attempt(models.Model):
    learner = models.ForeignKey(Learner, related_name='learnerattempts')
    word = models.ForeignKey(Word, related_name='wordattempts')
    when = models.DateTimeField(auto_now_add=True)
    success = models.BooleanField(default=False)

    class Meta:
        ordering = ['-when']

    class JSONAPIMeta:
        resource_name = "attempts"

    def __str__(self):
        formatted_when = localtime(self.when).strftime('%d-%b-%Y %X')
        if self.success:
            formatted_success = "YES"
        else:
            formatted_success = "NO"

        return u'%s - %s- Success ?: %s ' % (self.word, formatted_when, formatted_success)

编辑(和分辨率)

好吧,我对perform_create做了一些更改,似乎DRF以某种非常微妙的方式不喜欢嵌入pdb.set_trace。它不会吵闹地失败,但它只是没有响应。一旦我删除它,它就按我的预期工作了。

FWIW在调查过程中我也改变了

serializer.save

super().perform_create(serializer)

但事实上,一旦 pdb.set_trace 被删除,这两者中的任何一个都可以工作。

最佳答案

您可以在调用serializer.save方法后更新另一个模型。

def perform_create(serializer):
    serializer.save()
    ### here you can write the other logic of update
    ### you can use the signal, just raise signal on save of that model

关于Django休息框架: Correct way to override perform_create in ModelViewSet?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50835719/

相关文章:

css - 我的 html 文件中可以有多个 css 文件吗?

python - Django Rest 嵌套序列化器的 AttributeError

python - 如何在django中制作像google表单一样的表单?用户可以在哪里根据需要添加或删除字段?用户最多可以添加10-20个字段?

django - 如何在django测试中使用默认数据库

python-3.x - DRF ViewSet 额外操作 (`@action` )serializer_class

Django按属性子类过滤查询集

python - 使用最新的 Graphite 烯和 Graphite 烯-django版本时导入(无法从 'ResolveInfo' 导入名称 'graphql' )错误

django - MongoEngine 中对 EmbeddedDocumentListField 的大于 (gte) 查询

python - DRF 不会将原始 JSON 字符串发送到浏览器。它返回一个 JSON 字符串,想要绕过调用 json.load

使用自定义表单的 Django 内联表单集