Ich habe kürzlich erfahren, dass Sie die get-Methode überschreiben sollten, wenn Sie speziell etwas anderes als die Standardansicht tun möchten:
class ExampleView(generic.ListView):
template_name = 'ppm/ppm.html'
def get(self, request):
manager = request.GET.get('manager', None)
if manager:
profiles_set = EmployeeProfile.objects.filter(manager=manager)
else:
profiles_set = EmployeeProfile.objects.all()
context = {
'profiles_set': profiles_set,
'title': 'Employee Profiles'
}
Das ist einfach genug, aber wann sollte ich es verwenden get_queryset
oder get_context_data
darüber hinaus get
? Mir scheint, dass sie im Grunde das Gleiche tun oder fehlt mir nur etwas? Kann ich sie zusammen verwenden? Dies ist für mich eine große Verwirrung.
Um es noch einmal zu wiederholen: In welchen Fällen würde ich verwenden, um zu überwinden get_queryset
oder get_context_data
umgekehrt?
get
, und schon gar nicht in diesem Fall. Hier sollten Sie nur überschreibenget_context_data
.Antworten:
Sie machen tatsächlich verschiedene Dinge.
get()
Dies ist ein Top-Level - Verfahren, und es gibt einen für jede HTTP - Verb -
get()
,post()
,patch()
etc. Sie würden es außer Kraft setzen , wenn Sie etwas tun wollen , bevor ein Antrag der Ansicht verarbeitet wird, oder danach. Dies wird jedoch nur aufgerufen, wenn eine Formularansicht zum ersten Mal geladen wird, nicht, wenn das Formular gesendet wird. Grundlegendes Beispiel in der Dokumentation . Standardmäßig wird nur die konfigurierte Vorlage gerendert und der HTML-Code zurückgegeben.class MyView(TemplateView): # ... other methods def get(self, *args, **kwargs): print('Processing GET request') resp = super().get(*args, **kwargs) print('Finished processing GET request') return resp
get_queryset()
Wird von
ListView
s verwendet - bestimmt die Liste der Objekte, die Sie anzeigen möchten. Standardmäßig erhalten Sie nur alles für das von Ihnen angegebene Modell. Durch Überschreiben dieser Methode können Sie diese Logik erweitern oder vollständig ersetzen. Django-Dokumentation zu diesem Thema .class FilteredAuthorView(ListView): template_name = 'authors.html' model = Author def get_queryset(self): # original qs qs = super().get_queryset() # filter by a variable captured from url, for example return qs.filter(name__startswith=self.kwargs['name'])
get_context_data()
Diese Methode wird verwendet, um ein Wörterbuch zu füllen, das als Vorlagenkontext verwendet werden soll. Zum Beispiel füllt
ListView
s das Ergebnisget_queryset()
wieauthor_list
im obigen Beispiel aus. Sie werden diese Methode wahrscheinlich am häufigsten überschreiben, um Dinge hinzuzufügen, die in Ihren Vorlagen angezeigt werden sollen.def get_context_data(self, **kwargs): data = super().get_context_data(**kwargs) data['page_title'] = 'Authors' return data
Und dann können Sie in Ihrer Vorlage auf diese Variablen verweisen.
<h1>{{ page_title }}</h1> <ul> {% for author in author_list %} <li>{{ author.name }}</li> {% endfor %} </ul>
Um Ihre Hauptfrage zu beantworten, haben Sie so viele Methoden, dass Sie Ihre benutzerdefinierte Logik auf einfache Weise punktgenau festhalten können. Dadurch kann Ihr Code nicht nur lesbarer und modularer, sondern auch besser getestet werden.
Die Dokumentation sollte alles erklären. Wenn immer noch nicht genug, finden Sie möglicherweise auch die Quellen hilfreich. Sie werden sehen, wie alles mit Mixins implementiert wird, die nur möglich sind, weil alles unterteilt ist.
quelle
get_context_data()
erstelle, warum brauche ich es dann nochget_query_set()
und wie kann ich es entfernen, wenn ich es nicht verwende?Schauen wir uns die Standardimplementierung der ListView-
get
Methode an:https://github.com/django/django/blob/92053acbb9160862c3e743a99ed8ccff8d4f8fd6/django/views/generic/list.py#L158
class BaseListView(MultipleObjectMixin, View): """ A base view for displaying a list of objects. """ def get(self, request, *args, **kwargs): self.object_list = self.get_queryset() allow_empty = self.get_allow_empty() if not allow_empty: # When pagination is enabled and object_list is a queryset, # it's better to do a cheap query than to load the unpaginated # queryset in memory. if (self.get_paginate_by(self.object_list) is not None and hasattr(self.object_list, 'exists')): is_empty = not self.object_list.exists() else: is_empty = len(self.object_list) == 0 if is_empty: raise Http404(_("Empty list and '%(class_name)s.allow_empty' is False.") % {'class_name': self.__class__.__name__}) context = self.get_context_data() return self.render_to_response(context)
Sie werden feststellen, dass dies
get_queryset
in der ersten Zeile aufgerufen wird. Sie können dies einfach überschreiben, wenn Sie den Abfragesatz Ihres Modells nach dem Anwenden von Filterung / Bestellung usw. nur zurückgeben möchten.Sie müssen dafür nicht die gesamte
get
Methode überschreiben , da Ihnen all diese bereitgestellten Funktionen fehlen, z. B. Paginierung, 404 Überprüfungen usw.get_context_data
führt das resultierende Abfrageset zusammen mit Kontextdaten wie Querystring-Parametern für die Paginierung usw. zusammen.Was ich empfehlen würde, wäre, ab und zu mit der Quelle von django zu sprechen und zu versuchen, sie ein wenig zu verstehen, damit Sie die am besten geeignete Methode erkennen, die Sie überschreiben / ersetzen können.
quelle