How to get request in ModelResource django-import-export
Asked Answered
F

3

6

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
Finke answered 28/7, 2018 at 9:44 Comment(3)
I have not used django-import-export, but have you tried self.request?Gumm
Yes. of course but it doesn't has 'request' like in default Model Class. That's why it throws AttributeError object has no attribute 'request'Finke
Well, as I did not work with this library, all I can suggest is to place breakpoint into get_queryset method and inspect stacktrace. Somewhere in the stacktrace there will be a request and you can see how is it going to ModelResourceGumm
F
2

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)
Finke answered 28/7, 2018 at 11:35 Comment(0)
W
6

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
Walkerwalkietalkie answered 20/11, 2018 at 0:11 Comment(0)
F
2

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)
Finke answered 28/7, 2018 at 11:35 Comment(0)
M
0

Exporting custom data worked this way for me:

from django.contrib import admin
from import_export.admin import ExportMixin
from import_export.resources import ModelResource
from jobs.models import Job

class JobResources(ModelResource):
    class Meta:
        model = Job
        fields = ('id', 'foo', 'bar')

class JobAdmin(ExportMixin, admin.ModelAdmin):
    resource_class = JobResources

    fieldsets = (...)

Good luck folks!

Maraschino answered 6/7, 2021 at 12:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.