2009-04-07 14 views
15

ho aggiunto un metodo 'highlight_link' alla classe admin.py del mio modello:Django Admin: come accedere all'oggetto richiesta in admin.py, per i metodi 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) 

Si restituisce un link personalizzato per (ho lasciato fuori highlight_link.short_description per brevità) ogni record restituito nel cambiamento elenco. Che è grandioso. Ma mi piacerebbe ispezionare la stringa di query corrente e modificare il collegamento personalizzato basato su quello. C'è un modo per accedere all'oggetto Richiesta all'interno di "highlight_link"?

+0

vorrei far notare questo biglietto correlato: https: // codice .djangoproject.com/ticket/13659 – Paolo

risposta

0

Ho provato il altre risposte lasciate qui e incappate in problemi che per me stavano diventando complessi. Ho giocato con def __call__() e ho trovato il seguente. Questo probabilmente non è il modo corretto per fare questo, ma funziona ...

afferrare la variabile arrivare qui (tutti a RadioGridAdmin classe come sopra descritto nel mio post iniziale):

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

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

e dal è globale, è ora possibile accedere qui:

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

globals sono pericolosi nel contesto di ambienti multi-thread, come come in mod_phyton su server Apache. – Ber

3

Non è un modo diretto per farlo. Vedo 2 possibili soluzioni.

  • un negozio la gente del posto thread per lo stesso oggetto di richiesta

    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') 
    
  • Se si utilizza l'installazione semplice Django non filettato è possibile salvare la richiesta oggetto proprio come attributo:

    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

Non intendi "se stai usando semplice ** non ** - thr installazione di Django in rilievo "? –

+0

Sì, certo. È il mio errore di battitura. –

+0

Qual è l'impatto utilizzando l'uno o l'altro di questi due scenari? – 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

Override metodi del ModelAdmin è un modo abbastanza pulito ma il codice ha alcuni errori: "def highlight_link (self):" dovrebbe essere "def highlight_link (self, obj):" e "super (RadioGridAdmin, self) .changelist_view (...) " dovrebbe avere un" ritorno "di fronte. – jnns

+6

Questo non è protetto da thread. Un thread locale risolverebbe questo. –

+1

@CollinAnderson Perché non è protetto da thread? Potresti spiegarmelo? Grazie! – mozillazg

-2

Cosa c'è di sbagliato in questo:

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

Non credo che highlight_link otterrebbe l'oggetto di richiesta passato ad esso. –

+1

Quando un metodo è elencato come campo, verrà chiamato automaticamente per generare l'HTML per il campo, e viene chiamato con un certo insieme di argomenti, 'request' non è uno di questi. La semplice aggiunta alla firma del metodo non cambia il modo in cui viene chiamato. – brianmearns

11

I solv e il mio problema in questo modo.

class MyClassAdmin(admin.ModelAdmin): 

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

Ora posso usare self.request in qualsiasi luogo

UPDATE

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

Sembra ancora funzionare, ma 'queryset' deve ora essere sostituito con' get_queryset'. – sebhaase

+2

Funziona ancora in 1.9 ma 'queryset' deve ora essere sostituito con' get_queryset'. – sebhaase

+0

@sebhaase grazie, ho aggiornato la mia risposta. –

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

ciao, con django 1.9.6 'dall'importazione django.core get_thread_local_request' restituisce' ImportError: impossibile importare il nome 'get_thread_local_request''. Qualsiasi aiuto? – Paolo

+0

@Paolo aggiornamento risposta;) – react

Problemi correlati