Mam model zamówień w aplikacji sklepu internetowego, z automatycznie zwiększającym się kluczem podstawowym i kluczem obcym dla siebie, ponieważ zamówienia można podzielić na wiele zamówień, ale związek z oryginalnym zamówieniem musi być zachowany.Django: uzyskiwanie dostępu do instancji modelu z poziomu programu 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
Zarejestrowałem klasę OrderAdmin dla strony administracyjnej. W widoku szczegółów dodałem atrybut parent_order
w atrybucie fieldsets
. Oczywiście domyślnie wyświetla listę wszystkich zamówień w polu wyboru, ale nie jest to pożądane zachowanie. Zamiast tego dla zamówień, które nie mają zamówienia nadrzędnego (tj. Nie zostały podzielone z innego zamówienia, parent_order
ma wartość NULL/None), nie powinny być wyświetlane żadne zamówienia. W przypadku zamówień, które zostały podzielone, powinno być wyświetlane tylko jednoosobowe zamówienie.
Dostępna jest całkiem nowa metoda ModelAdmin, formfield_for_foreignkey
, która wydaje się idealna do tego, ponieważ zestaw zapytań można filtrować wewnątrz niego. Wyobraźmy sobie, że patrzymy na szczegółowy widok zamówienia nr 11234, który został podzielony na zamówienie nr 11208. Kod jest poniżej
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)
komentowanym rząd działa, gdy uruchomić w powłoce Pythona, wracając do queryset pojedynczego elementu zawierającego zamówienie # 11208 # 11234 i dla wszystkich innych zleceń, które mogły zostać podzielone z niego.
Nie możemy oczywiście zakodować tam numeru zamówienia. Potrzebujemy odniesienia do pola ordernumber
instancji zamówienia, której stronę szczegółów szukamy. W ten sposób:
kwargs["queryset"] = Order.objects.filter(child_orders__ordernumber__exact=?????)
Nie znalazłem działającego sposobu na zastąpienie ????? z odniesieniem do "aktualnej" instancji Orderu, a ja wykopałem dość głęboko. self
wewnątrz formfield_for_foreignkey
odnosi się do instancji ModelAdmin i chociaż ma atrybut model
, nie jest to instancja modelu zamówienia (jest to odwołanie do ModelBase, self.model() zwraca instancję, ale jej numer porządkowy to Brak).
Jednym z rozwiązań może być pobranie numeru zamówienia z request.path (/ admin/orders/order/11234 /), ale to jest naprawdę brzydkie. Naprawdę chcę, żeby był lepszy sposób.
To działa! Dziękuję bardzo!Jestem całkowicie nowy w całym tym modelu ModelForm/ModelAdmin i szukałem w niewłaściwym miejscu. –
Zdaję sobie sprawę, że ten post jest stary, ale działało to również jako przyzwoite obejście dla mnie dla get_readonly_fields na InlineModelAdmin, ponieważ przekazany do niego parametr obj jest obecnie obiektem nadrzędnym, a nie obiektem instancji wbudowanej. Dla wszystkich intencji i celów uczyniło to mój obiekt tylko do odczytu, pozwalając mi tylko zwrócić pojedynczy obiekt do mojego klucza obcego. – dgraves
Upewnij się, że najpierw wywołasz super .__ init__. To ustawia self.instance. – yellottyellott