0

I am new to the Django Framework and can't seem to identify why my detail.html is not rendering properly. It appears as though my forloop that iterates over choice in question.choice_set.all is not being hit. If someone could help identify why it would be very helpful.

detail.html

<h1>{{ question.question_text }}</h1> {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} <form action="{% url 'polls:vote' question.id %}" method="post"> {% csrf_token %} {% for choice in question.choice_set.all %} <label for="choice{{ forloop.counter }}">{{ choice.choice_text }} </label><br /> <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" /> {% endfor %} <input type="submit" value="Vote" /> </form> 

Views.py

from django.http import HttpResponseRedirect, HttpResponse from django.template import loader from django.urls import reverse from django.shortcuts import get_object_or_404, render from .models import Choice, Question # Long Method of return HttpResponse # def index(request): # latest_question_list = Question.objects.order_by('-pub_date')[:5] # template = loader.get_template('polls/index.html') # context = { # 'latest_question_list': latest_question_list, # } def index(request): latest_question_list = Question.objects.order_by('pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context) # render takes the request (object,template,dictionary<optional>) # def detail(request, question_id): # try: # question = Question.objects.get(pk=question_id) # except Question.DoesNotExist: # raise Http404("Question does not exist") # return render(request, 'polls/detail.html', {'question': question}) # SHORTCUT TO USE GET AND RASIE 404 def detail(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/detail.html', {'question': question}) def results(request, question_id): question = get_object_or_404(Question, pk=question_id) return render(request, 'polls/results.html', {'question': question}) 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 an HttpResponseRedirect after successfully dealing # with POST data. This prevents data from being posted twice if a # user hits the Back button. return HttpResponseRedirect(reverse('polls:results', args=(question.id,))) 

urls.py

# map views to url from django.conf.urls import url from django.conf.urls import include from . import views app_name = 'polls' urlpatterns = [ #ex: polls/ url(r'^$', views.index, name='index'), #ex: /polls/5/ url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'), #ex: /polls/5//results/ url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'), #ex: /polls/5/vote url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'), ] 

** Here is my data model** model.py

# Pythons Imports for built in modules import datetime from django.db import models from django.utils import timezone class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') #string method for question object representation def __str__(self): return self.question_text def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1) class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) def __str__(self): return self.choice_text # Running python manage.py makemigrations polls instructs django of # changes to your model 
3
  • Question model please? Commented Dec 31, 2016 at 1:50
  • I have added my model, also by error I am referring to my output continuing to fall through to "you didn't select a choice" in my Forloop. Commented Dec 31, 2016 at 5:39
  • My answer below is not correct. the choice_set is perfectly valid in the template. The work around is also fine. I'm not sure what exactly caused the problem now. Commented Dec 31, 2016 at 14:02

4 Answers 4

1

Register "Choice" in "polls/admin.py"

from django.contrib import admin from .models import Question from .models import Choice admin.site.register(Question) admin.site.register(Choice) 

After that add some choices in your admin panel and you're good to go.

Sign up to request clarification or add additional context in comments.

Comments

1

Here we have created two models i.e. "Question" & "Choice".

By following the tutorial we have added data in Question model by using our Admin privilege. But we have not added anything in "Choice" table that's why "question.choice_set.all" is returning nothing(null) and because of that the "{% for choice in question.choice_set.all %}" is not executing.

I have just added a line of code for demo in details.html

{{ question.question_text }} {{ question.choice_set.all }} {% if error_message %}<p><strong>{{ error_message }}</strong></p>{%endif %} 

enter image description here

Here as we can see QuerySet is empty.

I have manually entered data in "Choice" table after that when I am executing my code I am getting radio button and label in output which was expected and it shows that for loop is working. enter image description here

While entering data in Choice table just keep in mind that question_id is foreign key in choice table. So its value should match any one value of id from question table.

There might be other better solution, but this is what I have figured out. I am also a newbie trying to learn django.

Happy Coding!!

Comments

0
choice_set.all relatedclasslowercasename_set.all 

Reference:

https://www.reddit.com/r/django/comments/22poxo/basic_django_tutorial_question_about_pchoice/

Comments

-1

As a work around, you can add a function to your question model that grabs all relative information and generates a dictionary. Pass the dictionary through and you can access the information through the template.

This is a small example in my project

models.py under the student class

def get_homework(self): '''get all homeworks of classes related to this student''' dict = {} dict['notification'] = False dict['content'] = {} for my_class in self.related_class.all(): homework_list = [] for class_homework in my_class.related_homework.filter(due_date__gte=date.today()): if class_homework.due_date == date.today(): dict['notification'] = True homework = {} homework['name_chinese'] = class_homework.name_chinese homework['assigned_by'] = class_homework.assigned_by homework['homework_content'] = class_homework.homework_content homework['assign_date'] = class_homework.assign_date homework['due_date'] = class_homework.due_date homework['submission'] = class_homework.submission homework_list.append(homework) dict['content'][my_class.name_chinese] = homework_list return dict 

views.py

dict = student.get_homework() return render(request,'ParentHomework.html',dict) 

2 Comments

Sorry, this is just flat out wrong. That code is perfectly valid in a template.
@DanielRoseman you were right. I tried myself and its working fine. Should I delete? It just seems not intuitive for me to do query in the template logic.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.