2009-04-07 19 views
15

He añadido un método 'highlight_link' a la clase admin.py de mi modelo:Administrador de Django: ¿Cómo acceder al objeto de solicitud en admin.py, para los métodos de list_display?

class RadioGridAdmin(admin.ModelAdmin): 

    list_display = ('start_time', highlight_link) 

    def highlight_link(self): 
     return ('some custom link') 


admin.site.register(RadioGrid, RadioGridAdmin) 

Devuelve un enlace personalizado para (He dejado de lado highlight_link.short_description por razones de brevedad) cada registro devuelto en el cambio lista. Lo cual es genial. Pero me gustaría inspeccionar la cadena de consulta actual y cambiar el enlace personalizado en función de eso. ¿Hay alguna manera de acceder al objeto Request dentro de 'highlight_link'?

+0

me gustaría señalar este billete relacionada: https: // código .djangoproject.com/ticket/13659 – Paolo

Respuesta

0

He intentado con otras respuestas quedaron aquí y se encontraron con problemas que, para mí, se estaban volviendo complejos. Jugué con def __call__() y se me ocurrió lo siguiente. Esto probablemente no es la forma correcta de hacer esto, pero funciona ...

agarrar la variable llegar aquí (todos dentro RadioGridAdmin clase como se describe anteriormente en mi post inicial):

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

    return super(RadioGridAdmin, self).__call__(request, url) 

y desde es global, ahora se puede acceder desde aquí:

def highlight_link(self): 
    # access start_date here 
+3

Los elementos globales son peligrosos en el contexto de entornos de subprocesos múltiples, como como correr en mod_phyton en el servidor apache. – Ber

3

No es una forma directa de lograr esto. Veo 2 posibles soluciones

  • utilizar un almacén de los locales de rosca con el mismo objeto de solicitud

    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') 
    
  • Si está utilizando la instalación de Django no roscado sencillo que es posible ahorrar de peticiones de objetos tan atributo:

    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

No me refiero a "si está usando ** no ** simple - thr con la instalación de Django "? –

+0

Sí, por supuesto. Es mi error tipográfico –

+0

¿Cuál es el impacto usando uno u otro de estos dos escenarios? – Gelbander

15
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

Sustitución de métodos de la ModelAdmin es una manera bastante limpio pero el código tiene algunos errores: "def highlight_link (self):" debe ser "def highlight_link (auto, obj):" y "super (RadioGridAdmin, self) .changelist_view (...) " debe tener un" retorno "al frente. – jnns

+6

Esto no es seguro para la rosca. Un hilo local resolvería esto. –

+1

@CollinAnderson ¿Por qué no es threadsafe? ¿Podrías explicarme eso? ¡Gracias! – mozillazg

-2

¿Qué hay de malo en esto:

def highlight_link(self, request): 
    # access start_date here 
+2

No creo que highlight_link obtenga el objeto de solicitud que se le pasa. –

+1

Cuando un método se enumera como un campo, se llamará automáticamente para generar el HTML para el campo, y se llama con un cierto conjunto de argumentos, 'request' no es uno de ellos. Solo agregarlo a la firma del método no cambia la forma en que se llama. – brianmearns

11

I sølv e mi problema de esta manera.

class MyClassAdmin(admin.ModelAdmin): 

    def queryset(self, request): 
     qs = super(MyClassAdmin, self).queryset(request) 
     self.request = request 
     return qs 

ahora puedo usar self.request en cualquier lugar

ACTUALIZACIÓN

Changed in Django 1.6: The get_queryset method was previously named queryset.

class MyClassAdmin(admin.ModelAdmin): 

    def get_queryset(self, request): 
     qs = super(MyClassAdmin, self).get_queryset(request) 
     self.request = request 
     return qs 
+0

Parece que todavía funciona, pero 'queryset' ahora debe reemplazarse con' get_queryset'. – sebhaase

+2

Todavía funciona en 1.9 pero 'queryset' ahora debe reemplazarse con' get_queryset'. – sebhaase

+0

@sebhaase gracias, actualicé mi respuesta. –

0
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

hola, con django 1.9.6 'de django.core import get_thread_local_request' da' ImportError: no puede importar el nombre 'get_thread_local_request''. ¿Alguna ayuda? – Paolo

+0

@Paolo actualización respuesta;) – react

Cuestiones relacionadas