2017-01-06 2 views
0

Ich habe eine App, die dem Benutzer einige Fragen anzeigt. Es muss in Eingabetextfeldern antworten und dann gibt es eine Ansicht, die alle diese Ergebnisse überprüft (das folgende).Wie kann ich diese Django-Ansicht vereinfachen?

Diese Ansicht funktioniert perfekt, aber ich weiß, dass ich ein Durcheinander mit Wörterbüchern und Listen gemacht habe. Ich dachte, diese nur zu erstellen, um eine Ergebnisvariable vorzubereiten, die ich dann auf der HTML-Seite drucken werde. Wie kann ich es vereinfachen?

def check(request): 
    # Initialize results 
    results = [] 

    i = 0 
    for input_name, input_value in request.POST.items(): 

     # Remove cfsr from inputs 
     if input_name.isdigit(): 

      # Get the question from the input name 
      question = Question.objects.get(pk=input_name) 

      # Get the related correct answer to that question 
      answer = question.answer 

      # Create results 
      results.append({'question_text': question.text, 'user_answer': input_value, 
          'correct_answer': answer.text}) 

      # Check if user answer is correct 
      if input_value == answer.text: 
       results[i]['is_correct'] = True 
      else: 
       results[i]['is_correct'] = False 

      i += 1 

    context = {'results': results} 
    return render(request, 'quiz/results.html', context) 
+0

Sie sollten versuchen, Formulare zu verwenden, um das Quiz zu erstellen und die Antworten überprüfen. – hop

Antwort

3

Sie könnten diese Verbesserungen zur besseren Lesbarkeit machen:

  1. Erstellen Sie eine Liste der Eingänge, die Sie zugreifen möchten; Die if Prüfung für das Feld csrf_token macht den Code schwieriger zu lesen, und die Annahme, dass csrf_token immer Buchstaben enthält möglicherweise nicht wahr.

  2. Entfernen Sie die Zählervariable (i); Zähler wie diese in for Loops sind nicht pythonisch, und oft nur den Code komplizieren.

  3. Ersetzen Sie den if/else Test für die richtige Antwort mit einem booleschen Ausdruck; Das können Sie immer mit if/else Blöcken, die einfach True oder False an eine Variable je nach dem Ergebnis eines Tests zuweisen.
  4. Erstellen Sie das Ergebniswörterbuch vollständig, bevor Sie es an die Liste anhängen, damit Sie nicht über seinen Index (results[i]...) darauf zugreifen müssen.

    from django.http import HttpResponseNotAllowed, HttpResponseBadRequest 
    
    def check(request): 
        if not request.method == 'POST': 
         return HttpResponseNotAllowed(['POST']) 
    
        # guaranteed by CsrfViewMiddleware to exist 
        del request.POST['csrfmiddlewaretoken'] 
    
        results = [] 
        for question_id, user_answer in request.POST.items(): 
         try: 
          question = Question.objects.get(pk=name) 
         except Question.DoesNotExist: 
          return HttpResponseBadRequest("Oops!") 
    
         results.append({ 
          'question_text': question.text, 
          'user_answer': user_answer, 
          'correct_answer': question.answer.text, 
          'is_correct': value == question.answer.text, 
         }) 
    
        return render(request, 'quiz/results.html', { 
         'results': results, 
        }) 
    
+0

Das kann nicht stimmen ... woher kommt 'field'? – hop

+0

@hop Ja, es gibt nur dieses Problem für diese Antwort. Vielen Dank trotzdem –

+0

Ich denke, Ihre Verwendung von 'request.POST.items' ist auch in beiden Fällen falsch. – hop

2

Sie können

if input_value == answer.text: 
    results[i]['is_correct'] = True 
else: 
    results[i]['is_correct'] = False 

mit

results[-1]['is_correct'] = input_value == answer.text 

ersetzen und der i

besser loszuwerden

oder sogar könnten Sie das in der results.append

setzen
results.append({'question_text': question.text, 
       'user_answer': input_value, 
       'correct_answer': answer.text, 
       'is_correct': input_value == answer.text}) 
Verwandte Themen