2017-09-30 3 views
0

Ich arbeite jetzt seit ungefähr 3 Monaten mit Django und fühle, dass ich ein bisschen besser werde und arbeite mich zu klassenbasierten Ansichten hoch. Auf der Oberfläche erscheinen sie sauberer und leichter zu verstehen und in einigen Fällen sind sie es auch. In anderen nicht so sehr. Ich versuche eine einfache Dropdown-Ansicht über ModelChoiceField und ein Formular zu verwenden. Ich kann bekommen es mit einer Funktion basierend Ansicht zu arbeiten, wie unten in meiner views.py Datei gezeigt:Django Klassenbasierte Ansicht mit ModelChoiceField

def book_by_name(request): 
    form = BookByName(request.POST or None) 
    if request.method == 'POST': 
     if form.is_valid(): 
      book_byname = form.cleaned_data['dropdown'] 
      return HttpResponseRedirect(book_byname.get_absolute_url1()) 
    return render(request,'library/book_list.html',{'form':form}) 

Hier ist meine Form in forms.py ist:

class BookByName(forms.Form): 

    dropdown = forms.ModelChoiceField(queryset=Book.objects.none()) 

    def __init__(self, *args, **kwargs): 
     super(BookByName, self).__init__(*args, **kwargs) 
     self.fields['dropdown'].widget.attrs['class'] = 'choices1' 
     self.fields['dropdown'].empty_label = '' 
     self.fields['dropdown'].queryset = Book.objects.order_by('publisher') 

Dieser Code funktioniert. Wenn ich versucht habe, in eine klassenbasierte Ansicht zu konvertieren, beginnt das Problem. Ich habe versucht, so etwas wie dies in views.py zu tun:

class BookByNameView(FormView, View): 
    form_class = BookByName 
    initial = { 'Book' : Book } 
    template_name = 'library/book_list.html' 

    def get(self, request, *args, **kwargs): 
     form = self.form_class(initial=self.initial) 
     return render(request, self.template_name, {'form': form}) 

    def get_success_url(self, *args): 
     return reverse_lazy('library:book_detail', args = (self.object.id,)) 

Wenn diese mit der gleichen Form, ich ein Attribut Fehler erhalten,

‚BookByNameView‘ Objekt hat kein Attribut ‚Objekt‘.

Ich habe auch versucht, ListView und erhielt mehrere andere Fehler auf dem Weg. Das get_success_url muss auch einen Primärschlüssel aufnehmen und ich kann nicht herausfinden, wie man das auch bekommt. Wieder bin ich ein 3-monatiger Django-Neuling, also sei bitte sanft und danke im Voraus für deine Gedanken und Vorschläge! Ich fühle mich wie im Baseballstadion ... kann einfach meinen Platz nicht finden! Ich bin sehr offen dafür, das anders zu machen, wenn es einen saubereren/besseren Weg gibt, dies zu tun!

Basierend auf der neuesten Feedback, würde es die Klasse erscheinen Ansicht Basierend aussehen sollte:

class BookNameView(FormView): 
    form_class = BookName 
    template_name = 'library/book_list.html' 

    def get_success_url(self, *args): 
     return reverse_lazy('library:book_detail') 

dies richtig ist? Ich habe eine Testversion davon ausgeführt, und als Antwort auf Ihre Frage, warum ich überhaupt self.object.id verwende, versuche ich, den pk aus dem modelchoicefield zu bekommen, mit dem ich die Ansicht zurückgebe, die ich versuche zu bekommen . Dies kann sein, wo ich ein bisschen verloren bin. Ich versuche, die Detailansicht aus dem Dropdown-Listenfeld Modellauswahl zu erhalten und das ausgewählte Buch zurückzugeben. Allerdings kann ich das PK nicht erfolgreich an diese Sicht übergeben.

ich meinen Code aktualisiert ...

class BookByNameView(FormView, ListView): 
    model = Book 
    form_class = BookByName 
    template_name = 'library/book_list.html' 

    def get_success_url(self, *args): 
     return reverse_lazy('library:book_detail') 

Aber jetzt heißt es Fehler ... Reverse für 'book_detail' ohne Argumente nicht gefunden.

Antwort

0

Sie können die form_valid() - Funktion in FormView überschreiben, um zu erreichen, was Sie wollen. Wenn das Formular gültig ist, wird es an die Funktion form_valid() übergeben.

Versuchen Sie folgendes:

class BookByNameView(FormView): 
     model = Book 
     form_class = BookByName 
     template_name = 'library/book_list.html' 

     def form_valid(self, form): 
      bookbyname = form.cleaned_data['dropdown'] 
      return HttpResponseRedirect(bookbyname.get_absolute_url()) 
1

Warum verwenden Sie überhaupt self.object? Sie haben form.cleaned_data in der ursprünglichen Ansicht verwendet, das sollten Sie auch in der klassenbasierten Version verwenden. Beachten Sie, dass das Formular an form_valid übergeben wird.

Beachten Sie, dass Sie auch viele andere seltsame Dinge getan haben. Ihre get Methode ist sinnlos, ebenso wie Ihre Definition der initial dict; Sie sollten beide löschen. Außerdem erbt FormView bereits von View, Sie müssen View nicht explizit in Ihrer Deklaration anzeigen.

+0

Vielen Dank für die Zeit nehmen, meine Frage zu beantworten.Wie ich geschrieben habe, bin ich neu dabei, daher meine Frage im Forum. Können Sie bitte die Syntax näher erläutern? –

+0

Ich habe den Code basierend auf Ihren Kommentaren aktualisiert, liegt das näher an dem, was Sie vorschlagen? –

+0

Nachdem ich etwas mehr gespielt habe, habe ich die Ansicht aktualisiert, um eine ListView zu verwenden, die tut, was ich will, und lade eine Liste von Büchern in mein modelchoicefield. Das funktioniert gut. Wenn ich jedoch versuche, einen der Einträge in meinem modelchoice-Feld auszuwählen, scheint es, dass es nicht möglich ist, den einzelnen Datensatz anzuzeigen. Ich bin fast da... –

Verwandte Themen