Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get request in ModelResource django-import-export

How to get request.user from method queryset of ModelResource in django-import-export?

class PeopleResource(ModelResource):
    class Meta:
       model = People
       exclude = ('id','agent', 'public_id', 'active')

    def dehydrate_placeA(self, people):
        ...
        ...

    def get_queryset(self):
        query = People.objects.filter( ..... request.user )
        return query
like image 597
koderstory Avatar asked Mar 05 '23 17:03

koderstory


2 Answers

I was looking for something similar. I wanted the request object, based on the request made in the admin to export, to be attached to the Resource instance so I could inspect it and dynamically affect functionality based on query parameters. This would also be very useful if you wanted to change it dynamically based on User. It ended up being quite simple:

First, subclass the ModelResource class and look for a new kwarg:

from import_export import resources

class RequestModelResource(resources.ModelResource):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(RequestModelResource, self).__init__(*args, **kwargs)

Then, there is a relevant admin method in import-export you can use to pass kwargs. See here. Add this to your ModelAdmin that inherits from import_export.admin.ImportExportModelAdmin:

class MyModelAdmin(ImportExportModelAdmin):
    resource_class = MyModelResource

    def get_resource_kwargs(self, request, *args, **kwargs):
        """ Passing request to resource obj to control exported fields dynamically """
        return {'request': request}

That's basically it. Use the request now wherever you want in Resource classes that inherit from RequestModelResource. For example:

class MyModelResource(RequestModelResource):
    def get_export_fields(self):
        fields = super().get_fields()

        # Check self.request.user, self.request.GET, etc to impact logic
        # however you want!

        return fields
like image 126
timothyashaw Avatar answered Mar 16 '23 14:03

timothyashaw


Problem solved. I forget that I have called people_resource.export() in my views before. Now it easier because I just pass variabel kwargs in method export() and override def export() in model PeopleResource. So my solution is here.

views.py

def export_excel(request):    
    ...
    people_resource = PeopleResource()
    dataset = people_resource.export(agent=request.user.agent,)
    ...

models.py

class PeopleResource(ModelResource):
    class Meta:
        model = People
        exclude = ('id','agent', 'public_id', 'active')
    ...
    ...

    def export(self, queryset=None, *args, **kwargs):
        queryset = People.objects.filter(agent=kwargs['agent'])
        return super(PeopleResource, self).export(queryset, *args, **kwargs)
like image 38
koderstory Avatar answered Mar 16 '23 15:03

koderstory