2009-10-09 15 views
32

Stworzyłem niestandardowego menedżera dla modelu Django, który zwraca QuerySet trzymający podzbiór objects.all(). Potrzebuję tego jako domyślnego menedżera modelu, ponieważ tworzę także niestandardowy znacznik, który pobierze zawartość z dowolnego modelu (określonego przez argument) i musi użyć domyślnego menedżera dla określonego modelu. Wszystko to działa dobrze, z wyjątkiem - Django Admin również używa domyślnego Menedżera dla tego konkretnego modelu, co oznacza, że ​​nie wszystkie wystąpienia modelu pojawiają się w admin.Django - określ, który menedżer modelu Django admin powinien używać

Docs Django nie pomagają:

Jeśli używasz niestandardowych obiektów menedżera, wziąć pod uwagę, że pierwszy napotyka Menedżer Django (w kolejności, w jakiej są one zdefiniowane w modelu) ma specjalny status. Django interpretuje tego pierwszego menedżera zdefiniowanego w klasie jako "domyślnego" menedżera, a kilka części Django (, ale nie aplikacja administratora) użyje tego menedżera wyłącznie dla tego modelu. (Django Managers documentation)

Administrator nie ma użyć domyślnego menedżera, ale wydaje się, że w moim przypadku. Zauważ, że mam również wyraźnie dodać domyślny Menedżer objects:

subset = CustomManager() # the default manager 
objects = models.Manager() # the one I want admin to use 

Jak mogę określić, które Menedżer administrator powinien używać?

+0

Byłem też nogę przez sekcję podświetlonego w docs administratora. Jest to jeden z nielicznych przypadków, w których uważam, że dokumenty django są niejednoznaczne. – Alasdair

+0

Dziwne. Patrząc na najnowsze źródło Django, wygląda na to, że admin _does_ używa domyślnego menedżera. –

+1

@Michael admin użył domyślnego menedżera od przynajmniej Django 1.0. Kwestią tutaj jest raczej błąd w dokumentacji, który został naprawiony https://github.com/django/django/commit/f7814cdfe6c3b6d87bb8afdcc5c27ee2e92a6a62#docs/topics/db/managers.txt –

Odpowiedz

41

Możesz wybrać menedżera, zastępując metodę queryset w podklasie ModelAdmin.

def get_queryset(self, request): 
    # use our manager, rather than the default one 
    qs = self.model.objects.get_queryset() 

    # we need this from the superclass method 
    ordering = self.ordering or() # otherwise we might try to *None, which is bad ;) 
    if ordering: 
     qs = qs.order_by(*ordering) 
    return qs 
+0

Dzięki, to się stało! –

+0

jest "jeśli zamawianie:" konieczne? '*()' shoud działa! – caesarsol

+3

Zmienili nazwę metody na 'get_queryset' w Django 1.6. Stara nazwa jest teraz [przestarzała] (https://docs.djangoproject.com/en/1.6/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_queryset). –

6

Zaktualizowany kod:

def get_queryset(self, request): 
    """ 
    Returns a QuerySet of all model instances that can be edited by the 
    admin site. This is used by changelist_view. 
    """ 
    qs = self.model._default_manager.get_queryset() 
    # TODO: this should be handled by some parameter to the ChangeList. 
    ordering = self.get_ordering(request) 
    if ordering: 
     qs = qs.order_by(*ordering) 
    return qs 

_default_manager można zastąpić ...

+0

na Django 1.7 .7 aby to zadziałało, musiałem zastąpić '' '_default_manager'''' '' _base_manager''' – DoRivard

0

Jak oczekujemy objects być jedynym menedżer, administrator użyje manager w self.Admin.manager.

Od bilecie https://code.djangoproject.com/ticket/4754 otwartego troy.simpson

class filterManager(models.Manager): 
    def get_query_set(self): 
    return super(filterManager, self).get_query_set().filter(name='troy') 

class Blah(models.Model): 
    name = models.CharField(maxlength=100) 
    objects = filterManager() 
    class Admin: 
    manager = filterManager() 

testowane z Django 1.11

Powiązane problemy