Ich habe ein Modell für Bestellungen in einer Webshop-Anwendung, mit einem automatisch inkrementierenden Primärschlüssel und einem Fremdschlüssel für sich selbst, da Bestellungen in mehrere Bestellungen aufgeteilt werden können, aber die Beziehung zur ursprünglichen Bestellung beibehalten werden muss.Django: Zugriff auf die Modellinstanz von 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
Ich habe eine OrderAdmin-Klasse für die Verwaltungsseite registriert. Für die Detailansicht habe ich parent_order
in das Attribut fieldsets
aufgenommen. Natürlich listet dies standardmäßig alle Aufträge in einem Auswahlfeld auf, aber dies ist nicht das gewünschte Verhalten. Bei Aufträgen, die keinen übergeordneten Auftrag haben (d. H. Nicht von einem anderen Auftrag getrennt wurden; parent_order
ist NULL/None), sollten keine Aufträge angezeigt werden. Bei geteilten Aufträgen sollte nur die einzelne übergeordnete Bestellung angezeigt werden.
Es gibt eine ziemlich neue ModelAdmin-Methode, formfield_for_foreignkey
, die perfekt dafür scheint, da das Abfrage-Set darin gefiltert werden kann. Stellen Sie sich vor, wir sehen uns die Detailansicht der Bestellung # 11234 an, die von der Bestellnummer 11208 getrennt wurde. Der Code ist unter
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)
Die kommentierte Zeile funktioniert, wenn in einem Python-Shell läuft, einen Single-Artikel queryset Rückkehr enthält, um # 11208 für # 11234 und alle anderen Aufträge, die von ihm aufgespalten wurden.
Natürlich können wir dort die Bestellnummer nicht fest codieren. Wir benötigen einen Verweis auf das Feld ordernumber
der Bestellinstanz, dessen Detailseite wir betrachten. Gefällt mir:
kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=?????)
Ich habe keinen funktionierenden Weg gefunden zu ersetzen ????? mit einem Verweis auf die "aktuelle" Order-Instanz, und ich habe ziemlich tief gegraben. self
innerhalb formfield_for_foreignkey
bezieht sich auf die ModelAdmin-Instanz, und während das hat ein model
Attribut, es ist nicht die Auftragsmodellinstanz (es ist eine ModelBase-Referenz; self.model() gibt eine Instanz zurück, aber seine Bestellnummer ist None).
Eine Lösung könnte sein, die Bestellnummer aus request.path (/ admin/orders/order/11234 /) zu ziehen, aber das ist wirklich hässlich. Ich wünschte wirklich, es gäbe einen besseren Weg.
Es funktioniert! Ich danke dir sehr!Ich bin völlig neu in all dem ModelForm/ModelAdmin-Geschäft und habe an der falschen Stelle gesucht. –
Ich weiß, dass dieser Beitrag alt ist, aber dies funktionierte auch als eine gute Lösung für mich für get_readonly_fields auf einem InlineModelAdmin, da der übergebene obj-Parameter aktuell das übergeordnete Objekt und nicht das Objekt der Inline-Instanz ist. Für alle Absichten und Zwecke machte dies mein Objekt nur lesbar, indem ich nur ein einzelnes Objekt in meinen Fremdschlüssel zurückgeben konnte. – dgraves
Stellen Sie sicher, dass Sie zuerst super .__ init__ aufrufen. Das setzt Selbstzerstörung. – yellottyellott