Override get() in Django Class Based View zu Filtern
Fange ich eine neue app, und ich versuche mein bestes, Sie zu umarmen, Class-Based Views. Ahhh, Wachstumsschmerzen. Ich bin versucht zu tun, ein einfacher filter hier aus einer GET-Variablen, wenn es nicht existiert, möchte ich, um alle Objekte zurückzugeben, bestellt by id desc, wenn Sie es tut, ich will, um zu filtern, um-und Rückkehr der gefilterten Liste.
Schreibe ich 30+ Zeilen code um dies zu tun, so dass ich muss etwas falsch machen, richtig? Ich habe versucht, überschreiben get_queryset() und jetzt, dass ich an Sie denke, vielleicht sollte ich den Aufruf selbst.Anfrage.GET['Suche'] in get_queryset (), um das filtern. Gibt es einen standard-Weg, dies zu erreichen?
class MyModelList(AdminPageMixin, ListView):
model = MyModel
context_object_name = 'object'
template_name = 'template/list.html'
def get(self, request, *args, **kwargs):
if 'search' in request.GET and len(request.GET['search']):
search = request.GET['search']
self.object_list = MyModel.objects.filter(advertiser__name=search).orderby('-id')
context = self.get_context_data(object_list=self.object_list, search=search)
else:
self.object_list = MyModel.objects.all()
context = self.get_context_data(object_list=self.object_list).orderby('-id')
return self.render_to_response(context)
def get_context_data(self, **kwargs):
context = super(MyModelList, self).get_context_data(**kwargs)
form = MyModelForm
try:
context['search'] = kwargs['search']
except KeyError:
pass
context['form'] = form
context['form_action'] = reverse('mymodel-add')
context['form_display'] = 'hide'
context['form_save_label'] = 'Add'
return context
Sekundär, um die Sache zu verkomplizieren, habe ich eine CreateView und ein UpdateView, die ich gerne teilen möchte die get() oder get_queryset() und get_context_data() Methoden meiner ListView. Ich bin mir sicher, dass es ist möglich, mit einem Mixin, aber wieder, ich bin auf der Suche nach einem einheitlichen Weg, es zu tun. Vorschläge? Hier ist die CreateView, in denen ich teilen möchte, ListView Methoden.
class MyModelAdd(AdminPageMixin, CreateView):
model = MyModel
form_class = MyModelForm
context_object_name = 'object'
template_name = 'templates/list.html'
def get_success_url(self):
return reverse('mymodel-list')
def get_context_data(self, **kwargs):
context = super(MyModelAdd, self).get_context_data(**kwargs)
context['form_action'] = reverse('mymodel-add')
context['form_display'] = 'show'
context['object_list'] = MyModel.objects.all()
return context
def form_invalid(self, form):
form = MyModelForm(self.request.POST)
context = self.get_context_data()
context['form'] = form
context['form_action'] = reverse('mymodel-add')
context['form_display'] = 'show'
context['form_save_label'] = 'Add'
return render(self.request, 'templates/list.html', context)
- CBV bedeuten nicht unbedingt, dass weniger code
- Danke, @Samuele für diese Beobachtung. Ich werde hinzufügen, dass meine docstrings 😉
- class based views sind ein Schmerz, aber es langsam besser wird, wie Sie lernen, zu überarbeiten base Klassen besser.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ersten, du hast Recht in deiner Beobachtung: Sie sollten auf jeden Fall nutzen
get_queryset
für das filtern der Liste. Ich schlage vor, etwas entlang der Linien von:Zweitens, wenn Sie wirklich brauchen, um die Wiederverwendung von code zwischen der Liste und anderen Ansichten, Sie wären besser dran, schreibst eine eigene Funktion als ein mixin.
Anmerkung: Sie brauchen nicht die
form_action
URL in Ihrer form; einfachaction=""
und es wird POST zur gleichen URL.if search: qs = qs.filter(advertiser__name__icontains=search)
?Ist die beste Möglichkeit, zum filtern der Daten in "get_context_data'.