Search code examples
djangotastypie

How to access request object in django-tastypie custom serializer?


I have a middleware which modifies the request object based on the request

class MyMiddleware():
    def process_request(self, request):
        if request.path_info = "some special path":
            request.some_special_attribute = True
        return request

I have a resource using a custom serializer

class MyResource(ModelResource):
    name = fields.CharField("name")
    class Meta:
        serializer = MySerializer()


class MySerializer(Serializer):
    def from_json(self, content):
        if request.some_special_attribute:
            # modify the object and return

and the serializer must access the request object to return proper response object

Doesn't seem like there exists a way to do this.


Solution

  • I think you're confusing the job of the Resource and the job of the serializer. You shouldn't be trying to implement any business logic in your serializer; It's only for converting between json (or other) and a native python data structure.

    "and the serializer must access the request object to return proper response object". The Resource is for doing exactly that.

    I'd recommend reading through the docs where it talks about hydrating and dehydrating data. http://django-tastypie.readthedocs.org/en/latest/resources.html#advanced-data-preparation

    Here is an example from the docs where they've altered the request body based on an attribute in the request.

    class MyResource(ModelResource):
    
        class Meta:
            queryset = User.objects.all()
            excludes = ['email', 'password', 'is_staff', 'is_superuser']
    
        def dehydrate(self, bundle):
            # If they're requesting their own record, add in their email address.
            if bundle.request.user.pk == bundle.obj.pk:
                # Note that there isn't an ``email`` field on the ``Resource``.
                # By this time, it doesn't matter, as the built data will no
                # longer be checked against the fields on the ``Resource``.
                bundle.data['email'] = bundle.obj.email
            return bundle