django-requestlogs icon indicating copy to clipboard operation
django-requestlogs copied to clipboard

TypeError: 'str' object is not callable

Open anitstack opened this issue 4 years ago • 5 comments

I used custom MyEntrySerializer by extending BaseEntrySerializer bcz I was getting issue before (AttributeError: Got AttributeError when attempting to get a value for field user on serializer BaseEntrySerializer. The serializer field might be named incorrectly and not match any attribute or key on the RequestLogEntry instance. Original exception text was: 'User' object has no attribute 'username'.), but now getting different issue "TypeError: 'str' object is not callable" , Details are below. Traceback (most recent call last): File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner response = get_response(request) File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/middleware.py", line 20, in call get_requestlog_entry(request).finalize(response) File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/entries.py", line 96, in finalize self.store() File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/entries.py", line 100, in store storage.store(self) File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/storages.py", line 69, in store logger.info(self.prepare(entry)) File "/home/algoscale/Desktop/projects/parspec/venv/lib/python3.8/site-packages/requestlogs/storages.py", line 64, in prepare return self.get_serializer_class()(entry).data TypeError: 'str' object is not callable

please help to solve this one

anitstack avatar Apr 18 '21 07:04 anitstack

Hi, could you post the implementation of your MyEntrySerializer, as well as the REQUESTLOGS = {..} configuration in your settings.py?

Raekkeri avatar Apr 18 '21 12:04 Raekkeri

settings.py configuration for requestlogs

MIDDLEWARE = [ ......... ''requestlogs.middleware.RequestLogsMiddleware',' ]

REST_FRAMEWORK = { ......... 'EXCEPTION_HANDLER': 'requestlogs.views.exception_handler', }

REQUESTLOGS = { 'STORAGE_CLASS': 'requestlogs.storages.LoggingStorage', 'ENTRY_CLASS': 'requestlogs.entries.RequestLogEntry', 'SERIALIZER_CLASS': 'accounts.api.serializers.MyEntrySerializer', 'SECRETS': ['password', 'token'], 'ATTRIBUTE_NAME': '_requestlog', 'METHODS': ('GET', 'PUT', 'PATCH', 'POST', 'DELETE'), }

and my custom serializers class code is below:-

from requestlogs.storages import BaseEntrySerializer class UserSerializer(ModelSerializer):

class Meta:
        model = User
        fields = '__all__'

class MyEntrySerializer(BaseEntrySerializer): user = UserSerializer()

anitstack avatar Apr 19 '21 09:04 anitstack

I'm unable to reproduce the problem (couldn't get the exact same error), but seeing that the error is raised in requestlogs/storages.py", line 64, in prepare, there might be something funny going on with importing the entry serializer.

Anyway, I'd recommend for now to not use a ModelSerializer for the UserSerializer, but instead a normal Serializer and specifying the fields explicitly. Let me know if this helps.

Raekkeri avatar Apr 25 '21 12:04 Raekkeri

Hey @Raekkeri,

first of all, I want to thank you for this package because it is exactly what we are looking for!

I'm having the same issue as the original poster.

Edit: I've placed the serializer in a separate file and the issue is resolved. Previously I placed it next to existing serializers and I think this messes with the imports and settings

REQUESTLOGS = {
    'SERIALIZER_CLASS': 'myapp.serializers.LogEntrySerializer',
}
class LogEntrySerializer(serializers.Serializer):
    class ResponseSerializer(serializers.Serializer):
        status_code = serializers.IntegerField(read_only=True)
        # data = JsonDumpField(read_only=True)  # disabled on purpose because of sensitive data

    class UserSerializer(serializers.Serializer):
        id = serializers.IntegerField()
        username = serializers.CharField()

    action_name = serializers.CharField(read_only=True)
    execution_time = serializers.DurationField(read_only=True)
    timestamp = serializers.DateTimeField(read_only=True)
    ip_address = serializers.CharField(read_only=True)
    request = BaseRequestSerializer(read_only=True)
    response = ResponseSerializer(read_only=True)
    user = UserSerializer()

leads to:

TypeError: 'str' object is not callable

I've investigated a bit and populate_settings in base.py seems to resolve the class correctly. But the get_serializer_class function in BaseStorage seems to return only a string.

wilcoschoneveld avatar May 14 '21 09:05 wilcoschoneveld

Hey @Raekkeri,

first of all, I want to thank you for this package because it is exactly what we are looking for!

I'm having the same issue as the original poster.

Hi, thanks for looking into this issue. After a quick glance I still wasn't able to reproduce this issue in unit tests. So I'll leave this unresolved and get back to it later.

Raekkeri avatar May 21 '21 15:05 Raekkeri