Django rest框架为自定义日志覆盖initial会绕过OAuth初始化



我确信python中的类型层次结构和初始化肯定有一些我不了解的地方。。。我想用django-rest框架来记录post-bodys,就像这里在stackoverflow上建议的那样:通过覆盖initial和finalize_response。

这就是我的mixin的样子:

class LoggingMixin(object):
"""
Provides full logging of requests and responses
"""
def finalize_response(self, request, response, *args, **kwargs):
    # do the logging
    if settings.DEBUG:
        logger.debug("[{0}] {1}".format(self.__class__.__name__, response.data))
    return super(LoggingMixin, self).finalize_response(request, response, *args, **kwargs)
def initial(self, request, *args, **kwargs):
    # do the logging
    if settings.DEBUG:
        try:
            data = request._data
            logger.debug("[{0}] {1}".format(self.__class__.__name__, data))
        except exceptions.ParseError:
            data = '[Invalid data in request]'
    super(LoggingMixin, self).initial(self, request, *args, **kwargs)

我的观点:

class BulkScan(LoggingMixin, generics.ListCreateAPIView):
"""
Provides get (list all) and post (single) for scans.
"""
queryset = Scan.objects.all()
serializer_class = ScanSerializer
authentication_classes = (OAuth2Authentication,)
permission_classes = (IsAuthenticated,)
# insert the user on save
def pre_save(self, obj):
    for scan in obj:
        scan.user = self.request.user
def post(self, request, *args, **kwargs):
    serializer = ScanSerializer(data=request.DATA, many=True)
    if serializer.is_valid():
        self.pre_save(serializer.object)
        self.object = serializer.save(force_insert=True)
        self.post_save(self.object, created=True)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED,
                        headers=headers)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

然而,post或get请求失败,抱怨request.user属性不存在。这必须自动注入那里。如果我不覆盖initial,那么一切都很好,并且在调用APIView.initial时设置用户。

目前,我采用了重写getpost的方法,然后记录帖子正文的内容,但我不明白为什么在重写该方法时没有设置用户属性。

非常感谢你对此事的澄清。

您调用的initial的超级实现是错误的。不通过self:

super(LoggingMixin, self).initial(request, *args, **kwargs)

希望这能解决问题——似乎没有其他问题。

@carlton gibson是正确的,但还有一件事。我也有同样的问题。在进行日志记录之前,通过调用super()的initial()修复了此问题。

def initial(self, request, *args, **kwargs):
    # do the logging
    result = super(LoggingMixin, self).initial(request, *args, **kwargs)
    if settings.DEBUG:
        try:
            data = request._data
            logger.debug("[{0}] {1}".format(self.__class__.__name__, data))
        except exceptions.ParseError:
            data = '[Invalid data in request]'
    return result

最新更新