2012-09-10 31 views
46

Jeden z moich modeli został usunięty flaga, która jest używana do ukrycia przedmiotów globalnie:Zastąp domyślny queryset w Django administratora

class NondeletedManager(models.Manager): 
    """Returns only objects which haven't been deleted""" 

    def get_query_set(self): 
     return super(NondeletedManager, self).get_query_set().exclude(deleted=True) 

class Conversation(BaseModel): 
    ... 
    deleted = models.BooleanField(default=False) 
    objects = NondeletedManager() 
    all_conversations = models.Manager() # includes deleted conversations 

Jak mogę zastąpić domyślny queryset używany przez moduł administracyjny Django zawierać usunięte rozmowy?

+0

Czy naprawdę potrzebujesz niestandardowych menedżerów dla tych prostych zapytań? –

+2

Tak, usunięte obiekty powinny być ignorowane uniwersalnie (z wyjątkiem stron administracyjnych), więc warto ustawić domyślne. –

Odpowiedz

86

Możesz użyć metody overrideget_queryset w klasie administratora modelu.

class MyModelAdmin(admin.ModelAdmin): 
    def get_queryset(self, request): 
     qs = super(MyModelAdmin, self).get_queryset(request) 
     if request.user.is_superuser: 
      return qs 
     return qs.filter(author=request.user) 

Uwaga w Django < = 1,5 metoda została nazwana właśnie queryset.

+2

Jak by to działało w tym przypadku? Czy mogę zmodyfikować zestaw zapytań utworzony przez 'ModelAdmin.queryset', aby uwzględnić usunięte obiekty? Nie chcę sam budować zestawu zapytań zamiast wywoływać nadklasę. –

+0

Spójrz na moją odpowiedź, aby zobaczyć, co mam na myśli. Czy istnieje alternatywa do całkowitego ponownego wprowadzenia funkcji? –

+3

Pomaga właściwie umieścić odpowiedź w odpowiedzi, a nie tylko link. Ten link jest już martwy, więc zaktualizuję, aby podać wyjaśnienie. – Dan

2

Co byłoby tak źle z następujących czynności:

class Conversation(BaseModel): 
    ... 
    deleted = models.BooleanField(default=False) 
    objects = models.Manager() # includes deleted conversations 
    nondeleted_conversations = NondeletedManager() 

Więc własne aplikacje/projektów, należy użyć Conversation.nondeleted_conversations() i niech wbudowanego administratora aplikacji zrobić to rzeczą.

+1

Ignoruję usunięte obiekty wszędzie * ale * strony administratora, więc myślę, że powinno to być domyślne. Ponadto w ten sposób nie muszę aktualizować starszego kodu, dodając możliwość usuwania wątków. –

7

Konrad jest poprawny, ale jest to trudniejsze niż przykład podany w dokumentacji.

Usuniętych wątków nie można uwzględnić w zapytaniu, które już je wyklucza. Tak więc nie widzę opcji innej niż ponowne wdrożenie w całości polecenia admin.ModelAdmin.queryset.

class ConversationAdmin (admin.ModelAdmin): 

    def queryset (self, request): 
     qs = Conversation.all_conversations 
     ordering = self.get_ordering(request) 
     if ordering: 
      qs = qs.order_by(*ordering) 
     return qs 
+0

Nie sądzę, że coś jest nie tak z tym. Korzystanie z dwóch menedżerów jest drogą do zrobienia. Prawdą jest jednak, że administrator Django mógłby zapewnić hak, aby nie trzeba było ponownie wdrażać części zamawiającej. –

1

Przyjęte rozwiązanie działa świetnie dla mnie, ale ja potrzebowałem nieco większą elastyczność, więc skończyło się na rozszerzenie widoku listy zmian do dodania w parametrze niestandardowy queryset. Mogę teraz skonfigurować mój domyślny zestaw zapytań/filtr jako taki i nadal można go zmodyfikować za pomocą innego filtru (uzyskaj parametry):

def changelist_view(self, request, extra_context=None): 
    if len(request.GET) == 0 : 
     q = request.GET.copy() 
     q['status__gt'] = 4 
     request.GET = q 
     request.META['QUERY_STRING'] = request.GET.urlencode() 

    return super(WorksheetAdmin,self).changelist_view(request, extra_context=extra_context) 
Powiązane problemy