Eines meiner Modelle verfügt über ein gelöschtes Flag, mit dem Objekte global ausgeblendet werden:
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
Wie kann ich das vom Django-Verwaltungsmodul verwendete Standardabfrageset überschreiben, um gelöschte Konversationen einzuschließen?
django
django-models
django-admin
Natan Yellin
quelle
quelle
Antworten:
Sie können die
get_queryset
Methode in Ihrer Modelladministrationsklasse überschreiben .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)
Beachten Sie, dass in Django <= 1.5 die Methode nur benannt wurde
queryset
.quelle
ModelAdmin.queryset
, dass es gelöschte Objekte enthält? Ich möchte das Abfrageset nicht selbst erstellen, anstatt die Oberklasse aufzurufen.get_queryset
.Konrad ist richtig, aber dies ist schwieriger als das in der Dokumentation angegebene Beispiel.
Gelöschte Konversationen können nicht in ein Abfrageset aufgenommen werden, das sie bereits ausschließt. Daher sehe ich keine andere Option als die vollständige Neuimplementierung von 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
quelle
Was wäre mit folgendem so falsch:
class Conversation(BaseModel): ... deleted = models.BooleanField(default=False) objects = models.Manager() # includes deleted conversations nondeleted_conversations = NondeletedManager()
In Ihren eigenen Apps / Projekten verwenden
Conversation.nondeleted_conversations()
Sie die integrierte Admin-App und lassen sie das tun.quelle
Die akzeptierte Lösung funktioniert gut für mich, aber ich brauchte etwas mehr Flexibilität, sodass ich die Änderungslistenansicht erweitert habe, um einen benutzerdefinierten Abfragesatzparameter hinzuzufügen. Ich kann jetzt meinen Standard-Abfragesatz / Filter als solchen konfigurieren und er kann weiterhin mithilfe eines anderen Filters geändert werden (Parameter abrufen):
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)
quelle
Sie können dies mit einem Django- Proxy-Modell tun .
# models.py class UnfilteredConversation(Conversation): class Meta: proxy = True # this will be the 'default manager' used in the Admin, and elsewhere objects = models.Manager() # admin.py @admin.register(UnfilteredConversation) class UnfilteredConversationAdmin(Conversation): # regular ModelAdmin stuff here ...
Wenn Sie über eine vorhandene ModelAdmin-Klasse verfügen, möchten Sie diese erneut verwenden:
admin.site.register(UnfilteredConversation, ConversationAdmin)
Dieser Ansatz vermeidet Probleme, die beim Überschreiben des Standardmanagers im ursprünglichen Konversationsmodell auftreten können, da der Standardmanager auch in ManyToMany-Beziehungen und beim Umkehren von ForeignKey-Beziehungen verwendet wird.
quelle
Natan Yellin ist korrekt, aber Sie können die Reihenfolge der Manager ändern. Die erste ist die Standardeinstellung, dann wird sie vom Administrator verwendet:
class Conversation(BaseModel): ... deleted = models.BooleanField(default=False) all_conversations = models.Manager() # includes deleted conversations objects = NondeletedManager()
Die Administrator-Implementierung der
get_queryset()
Verwendung._default_manager
stattdessen.objects
, wie im Folgenden gezeigtqs = self.model._default_manager.get_queryset()
ref Django Github BaseModelAdmin Implementierung
Dies stellt nur sicher, dass Sie bei jeder Verwendung von YourModel.objects keine gelöschten Objekte einschließen, sondern die generischen Ansichten und andere auch ._default_manager verwenden. Wenn Sie get_queryset nicht überschreiben, ist dies keine Lösung. Ich habe gerade eine ListView und einen Administrator überprüft.
quelle