Ho un modello per gli ordini in un'applicazione webshop, con una chiave primaria a incremento automatico e una chiave esterna a se stessa, poiché gli ordini possono essere suddivisi in più ordini, ma la relazione con l'ordine originale deve essere mantenuta.Django: accede all'istanza del modello da ModelAdmin?
class Order(models.Model):
ordernumber = models.AutoField(primary_key=True)
parent_order = models.ForeignKey('self', null=True, blank=True, related_name='child_orders')
# .. other fields not relevant here
Ho registrato una classe OrderAdmin per l'amministratore del sito. Per la visualizzazione dettagliata, ho incluso parent_order
nell'attributo fieldsets
. Ovviamente, per impostazione predefinita questo elenca tutti gli ordini in una casella di selezione, ma questo non è il comportamento desiderato. Invece, per gli ordini che non hanno un ordine genitore (cioè non sono stati divisi da un altro ordine: parent_order
è NULL/Nessuno), non devono essere visualizzati ordini. Per gli ordini che sono stati divisi, questo dovrebbe visualizzare solo l'ordine genitore singolo.
C'è un nuovo metodo ModelAdmin disponibile, formfield_for_foreignkey
, che sembra perfetto per questo, poiché il set di query può essere filtrato al suo interno. Immagina di osservare la vista dettagliata dell'ordine n. 11234, che è stato diviso dall'ordine n. 11208. Il codice è inferiore
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'parent_order':
# kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=11234)
return db_field.formfield(**kwargs)
return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)
la fila commentato funziona quando eseguito in una shell Python, restituendo un queryset singolo elemento contenente ordine # 11208 per # 11234 e tutti gli altri ordini che possono essere stati divisi da esso.
Naturalmente, non è possibile codificare il numero dell'ordine. Abbiamo bisogno di un riferimento al campo ordernumber
dell'istanza dell'ordine di cui stiamo guardando la pagina dei dettagli. In questo modo:
Non ho trovato alcun modo di lavoro per sostituire ????? con un riferimento all'istanza dell'Ordine "corrente", e ho scavato piuttosto in profondità. self
all'interno di formfield_for_foreignkey
fa riferimento all'istanza ModelAdmin e sebbene abbia un attributo model
, non è l'istanza del modello di ordine (è un riferimento a ModelBase; self.model() restituisce un'istanza, ma il suo numero di ordine è Nessuno).
Una soluzione potrebbe essere quella di estrarre il numero di ordine da request.path (/ admin/orders/order/11234 /), ma questo è davvero brutto. Mi piacerebbe davvero che ci fosse un modo migliore.
Funziona! Grazie mille!Sono completamente nuovo a tutto questo business ModelForm/ModelAdmin e stavo cercando nel posto sbagliato. –
Mi rendo conto che questo post è vecchio, ma questo ha funzionato anche come soluzione decente per me per get_readonly_fields su un InlineModelAdmin poiché il parametro obj passato ad esso è attualmente l'oggetto genitore, non l'oggetto dell'istanza in linea. A tutti gli effetti, questo ha reso il mio oggetto readonly permettendomi di restituire un solo oggetto nel mio foreignkey. – dgraves
Assicurati di chiamare prima super .__ init__. Ciò definisce l'ego. – yellottyellott