Opened 14 years ago

Last modified 3 years ago

#13659 assigned New feature

Make the request accessible in callables used in ModelAdmin.list_display

Reported by: Sebastian Noack Owned by: Paulo
Component: contrib.admin Version: dev
Severity: Normal Keywords:
Cc: ionel.mc@…, django@…, andreas@… Triage Stage: Accepted
Has patch: yes Needs documentation: yes
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Its a nice feature of the dajngo admin that you can use names of model or model admin methods and plain callables in ModelAdmin.list_display. But I want show content in my custom column dependant on the logged in user. This isn't possible at the moment. But I have written a patch that passes the request object to the given callable or method, when it has the needs_request attribute and it is True.

Attachments (1)

pass_request_to_admin_display_callbacks.patch (8.0 KB ) - added by Sebastian Noack 14 years ago.

Download all attachments as: .zip

Change History (16)

comment:1 by Sebastian Noack, 14 years ago

Has patch: set

comment:2 by Jacob, 14 years ago

Needs documentation: set
Needs tests: set
Patch needs improvement: set
Triage Stage: UnreviewedAccepted

Nitpick: I'd name the function attribute accepts_request and not needs_request -- reads better to me. Other than that looks good, but needs docs and tests.

comment:3 by Sebastian Noack, 14 years ago

I agree, the name sounds better, indeed.

comment:4 by Sebastian Noack, 14 years ago

Needs tests: unset
Patch needs improvement: unset

I have updated the patch to django 1.2, renamed needs_request and have added a test, now.

by Sebastian Noack, 14 years ago

comment:5 by Gabe Jackson, 14 years ago

i think it would be better pass request in to the constructor of ModelAdmin and create an additional method "get_list_display" so one can dynamically set the list_display fields dependent of the request (i.e have a different list_display depending on request.user or similar). It might be even better to register ModelAdmin objects dynamically based on request instead of doing all this conditional get_* overrides in ModelAdmin.
Another question would be if it's possible to limit access of users to certain AdminSites. this would be another solution:
have multiple AdminSites and register the appropriate ModelAdmins. Currently I think that users may log in to any AdminSite though, or am I mistaking?

comment:6 by anonymous, 13 years ago

Cc: ionel.mc@… added

comment:7 by Julien Phalip, 13 years ago

Severity: Normal
Type: New feature

comment:8 by Julien Phalip, 13 years ago

Easy pickings: unset
Patch needs improvement: set

I think there's a problem with this patch. The request parameter in lookup_field could be None, which would happen when called from AdminReadonlyField.contents(). This means that the callable may receive None in some cases, which is a shame. The callable should always receive the HTTPRequest object.

Also, I think it would make more sense (and be more consistent with the way ModelAdmin's methods work) if the request was provided as the first argument, e.g.:

    def my_function(request, ...):
        ...

or:

    def my_method(self, request, ...):
        ...

And finally, I'd prefer the function attribute to be called takes_request, for consistency with takes_context in the inclusion_tag.

comment:9 by jedie, 13 years ago

Cc: django@… added
UI/UX: unset

comment:10 by Tim Graham, 9 years ago

Summary: Made the request accessible in callables used in ModelAdmin.list_display [PATCH]Make the request accessible in callables used in ModelAdmin.list_display
Version: 1.2master

comment:11 by Paulo, 8 years ago

Owner: changed from nobody to Paulo
Status: newassigned

comment:12 by Andreas Pelme, 7 years ago

Cc: andreas@… added

comment:13 by Dominik Bartenstein, 3 years ago

As callables in list_display don’t get the request object, is it safe to add the request object as attribute to the admin class object? In the callable it would then be possible to access the request via self.request to e.g. check if the current user has permission to edit the object.

Code sample:

def changelist_view(self, request, extra_context=None):
    self.request = request  # Is it safe to store the request?
    return super().changelist_view(request, extra_context)

comment:14 by Tim Graham, 3 years ago

No, storing state on the ModelAdmin class isn't thread-safe.

in reply to:  14 comment:15 by Dominik Bartenstein, 3 years ago

Replying to Tim Graham:

No, storing state on the ModelAdmin class isn't thread-safe.

Thanks a lot for the quick answer, Tim!

What approach do you recommend when the request object is to be considered in a callable used with list_display?
There is middleware such as https://github.com/jedie/django-tools/blob/master/django_tools/middlewares/ThreadLocal.py

Use case:
In the callable used with list_display the user’s permissions for each object have to be checked. Thus we need access to request.user.

Note: See TracTickets for help on using tickets.
Back to Top