2016-05-23 2 views
0

Noch immer auf der offiziellen Django-Tutorial, und ich habe ein Problem, wo ich überprüfen nicht, ob len(Question.objects.all()) gleich 0 ist halte ich diese bekommen Sie dieses Problem:Derzeit nach dem offiziellen Django-Tutorial, und ich kann nicht überprüfen, ob die Länge der Liste gleich 0 ist. Warum?

Could not parse the remainder: '(Question.objects.all())' from 'len(Question.objects.all())' 

und ich kann nicht sehen, warum diese passiert weiter.

Umfragen/templates/Umfragen/details.html

<h1> {{ question.question_text }} </h1> 

{% if error_message %}<p> <strong> {{ error_message }} </strong> </p> {% endif %} 
{% if len(Question.objects.all()) == 0 %} 
     <p> There are no choices! </p> 
{% else %} 
     <form action="{% url 'polls:vote' question.id %}" method="post"> 
       {% csrf_token %} 
       {% for choice in question.choice_set.all %} 
         <input type="radio" name="choice" id="choice{{ forloop.counter }}" 
         value="{{ choice.id }}"/> 
         <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label> 
         <br /> 
       {% endfor %} 
       <input type="submit" value="Vote" /> 
     </form> 
{% endif %} 

polls/views.py

from django.shortcuts import render, get_object_or_404 
from django.http import HttpResponse, HttpResponseRedirect 
from django.utils import timezone 
from django.core.urlresolvers import reverse 
from django.views import generic 

from .models import Choice, Question 

# Create your views here. 

class IndexView(generic.ListView): 
    template_name = 'polls/index.html' 
    context_object_name = 'latest_question_list' 

    def get_queryset(self): 
     # Returns the last five published questions 
     return Question.objects.filter(
       pub_date__lte=timezone.now()).order_by('-pub_date')[:5] 

class DetailView(generic.DetailView): 
    model = Question 
    template_name = 'polls/detail.html' 

    def get_queryqet(self): 
     """ Exclude any unpublished questions. """ 
     return Question.objects.filter(pub_date__lte=timezone.now()) 

class ResultsView(generic.DetailView): 
    model = Question 
    template_name = 'polls/results.html' 

def vote(request, question_id): 
    question = get_object_or_404(Question, pk=question_id) 
    try: 
     selected_choice = question.choice_set.get(pk=request.POST['choice']) 
    except(KeyError, Choice.DoesNotExist): 
     # Redisplay the question voting form. 
     return render(request, 'polls/detail.html', { 
      'question': question, 
      'error_message': "You didn't select a choice!", 
      }) 
    else: 
     selected_choice.votes += 1 
     selected_choice.save() 
     # Always return HttpResonseRedirect after POST success, prevents 
     # data from being posted twice if someone hits the back button! 
     return HttpResponseRedirect(reverse('polls:results', args=(question.id,))) 

Auch ist dies ein guter Weg, es zu tun? Oder sollte ich etwas mit views.py tun, ähnlich wie das IndexView die 5 neuesten Artikel herausfiltert. Wie kann ich das mit dem DetailView machen? Das len (Question.object.all()) funktioniert einwandfrei in der Shell, so dass ich nicht verstehe, warum es nicht funktioniert, wenn ich es in den Django-Vorlagen verwende.

Antwort

3

Das funktioniert definitiv nicht in Django-Vorlage. Selbst wenn es funktioniert, ist es eine schlechte Methode, die Länge des Django-Querysets zu messen. Denn wenn Sie len() tun, würde Python versuchen, die Listenlänge durch Zählen zu bewerten, wie viele Elemente vorhanden sind. Wenn Sie viele Ergebnisse haben, könnten Sie Probleme mit der Effizienz haben.

Sie sollten exists() für queryset ORM api verwenden:

if Question.objects.exists(): 
    # do something 

Ein weiteres Problem, das Sie haben, ist, dass Sie die ORM-Operationen in der Vorlage nicht tun können, weil die Modellnamen nicht verfügbar sind. Sie sollten IMMER IMMER so viel Logik wie möglich in views.py haben. So erstellen Sie eine Variable so etwas wie questions = Question.objects.all() genannt, dann tut dies in Vorlage:

{% if questions.exists %} 
{% else %} 
{% endif %} 

prüfen django doc über die common stuff that triggers the queryset evaluation.

Auch um die queryset zu Kontext hinzufügen, in DetailView, override function get_context_data.

+0

Oh, danke! Es hat zwar nicht funktioniert, aber ich habe erkannt, dass ich versucht habe, die Anzahl der Fragen in der Fragenliste zu überprüfen, als ich nach den Möglichkeiten suchen sollte, die mit der Frage verbunden sind. Ich werde das allerdings herausfinden. Noch einmal Danke – gloriousCatnip

Verwandte Themen