Django Admin: How to access the request object in admin.py, for list_display methods?

后端 未结 9 1703
太阳男子
太阳男子 2020-12-13 14:30

I\'ve added a method highlight_link to my model\'s admin.py class:

class RadioGridAdmin(admin.ModelAdmin):
    
    list_display = (\'start_time\         


        
相关标签:
9条回答
  • 2020-12-13 14:52

    Small code clarify for Diego Puente answer (python 3.6):

    class MyClassAdmin(admin.ModelAdmin):
        def __init__(self, model, admin_site): 
            self.request = None
            super().__init__(model, admin_site)
    
        def get_queryset(self, request):
            self.request = request      
            return super().get_queryset(request)
    

    So you can get self.request from any other method of MyClassAdmin.

    If define self.request in get_queryset method (without declaring it in __init__) PyCharm will generate warning Instance attribute attribute_name defined outside __init__.

    0 讨论(0)
  • 2020-12-13 14:57
    class RadioGridAdmin(admin.ModelAdmin):
    
        def highlight_link(self, obj):
            return (self.param)
    
       def changelist_view(self, request, extra_context=None):
            self.param = request.GET['param']
            return super(RadioGridAdmin,self).changelist_view(request, extra_context=extra_context)
    
    0 讨论(0)
  • 2020-12-13 14:59
    import threading
    
    _thread_local = threading.local()
    
    def get_thread_local_request():
        return getattr(_thread_local, "request", None)
    
    class RadioGridAdmin(admin.ModelAdmin):
        list_display = ('display_field', ...)
    
        def display_field(self, obj):
            # ...
            request = get_thread_local_request()
            # ... 
    
    0 讨论(0)
  • 2020-12-13 15:09

    I tried the other answers left here and ran into issues that for me, were getting complex. I played around with def __call__() and came up with the following. This probably isn't the correct way to do this, but it works...

    grab the GET variable here (all within class RadioGridAdmin as described above in my initial post):

    def __call__(self, request, url):
         global start_date
         start_date = request.GET['param']
    
         return super(RadioGridAdmin, self).__call__(request, url)
    

    and since it's global, you can now access it here:

    def highlight_link(self):
        # access start_date here
    
    0 讨论(0)
  • 2020-12-13 15:11

    This is edited version of @user27478 answer, which uses thread-local vars:

    class RadioGridAdmin(admin.ModelAdmin):
        def __init__(self, model, admin_site):
            super().__init__(model, admin_site)
            self._request_local = threading.local()
    
        def changelist_view(self, request, extra_context=None):
            self._request_local.request = request
            return super().changelist_view(request, extra_context)
    
        @property
        def _request(self):
            return self._request_local.request
    
        def example_highlight_link(self, obj):
            changelist = self.get_changelist_instance(self._request)
            url = changelist.get_query_string(new_params={'key1': 1})
    
    0 讨论(0)
  • 2020-12-13 15:13

    The is no direct way to accomplish this. I see 2 possible solutions.

    • Use a thread locals store to same request object

      from django.utils._threading_local import locals
      
      globals = locals()
      
      class RadioGridAdmin(admin.ModelAdmin):
        def __call__(self, request, *args, **kwargs):
            globals['radio_grid_admin_request'] = request
            return super(RadioGridAdmin, self).__call__(request, *args, **kwargs)
      
        def highlight_link(self):
            request = globals['radio_grid_admin_request']
            # request.GET processing
            return ('some custom link')
      
    • If you are using simple non-threaded Django installation it is possible to save request object just as attribute:

      class RadioGridAdmin(admin.ModelAdmin):
        def __call__(self, request, *args, **kwargs):
            self.request = request
            return super(RadioGridAdmin, self).__call__(request, *args, **kwargs)
      
        def highlight_link(self):
            # self.request.GET processing
            return ('some custom link')
      
    0 讨论(0)
提交回复
热议问题