MNNIT CC 2021-22 Classes

Web Development Class - VII

Web Development Class - VII recording: Here

May 14, 2021

Polling App in Django (Continued)

Recap: Steps involed in Making/Editing a Table/Model in Django

Interacting with database using CLI

python manage.py shell
ques_qs = Question.objects.filter(id=1)
if ques_qs:
    ques_obj = ques_qs[0]  # ques_qs.first()

# OR
ques_obj = Question.objects.filter(id=1)[0]

# OR
ques_obj = Question.objects.filter(id=1).first()
new_ques = Question.objects.create(question_text="New Question", publication_date=timezone.now())
ordered_ques = Question.objects.order_by('publication_date')

# Reversing order

reverse_ordered_ques = Question.objects.order_by('-publication_date')

Creating Choices for questions

>>> choice1 = Choice(choice_text="GUI", number_of_votes=0, question=new_ques)
>>> choice1.save()
>>> choice2 = Choice.objects.create(choice_text="CLI", number_of_votes=0, question=new_ques)
# In polls/models.py
class Choice(models.Model):
	...
	number_of_votes = models.IntegerField(default=0, verbose_name="Number of Votes")
	...

Main Page of Polls App

# In project1/urls.py

urlpatterns = [
	path("polls/", include("polls.urls")),
	path("admin/", admin.site.urls),
]
# In polls/urls.py
from polls import views

urlpatterns = [
	path('', views.main_page, name="Main Page"),
	# Eg: http://127.0.0.1:8000/polls

	path('<int:ques_id>/details/', views.details, name="Details"),
	# Eg: http://127.0.0.1:8000/polls/1/details	, where ques_id=1

	path('<int:ques_id>/results/', views.results, name="Results"),	
	# Eg: http://127.0.0.1:8000/polls/1/results , where ques_id=1

	path('<int:ques_id>/vote/', views.vote, name="Vote"),	
	# Eg: http://127.0.0.1:8000/polls/1/vote , where ques_id=1

]
# In polls/views.py file
from django.shortcuts import HttpResponse
from polls.models import Question

def main_page(request):

	response = "This page will show list of all questions"

	return HttpResponse(response)


def details(request, ques_id):

	response = "This page will show Details of question with id=" + str(ques_id)
	return HttpResponse(response)


def results(request, ques_id):

	response = "This page will show Results of voting on question with id=" + str(ques_id)
	return HttpResponse(response)


def vote(request, ques_id):
	print("Voting on question with id=" + str(ques_id))
	pass

Django templates

# In polls/views.py file
from django.shortcuts import render, HttpResponse
from polls.models import Question

def main_page(request):

	# Fetching list of all questions
	all_questions_qs = Question.objects.all()

	print("Question List successfully fetched!")

	return render(request, "polls/main_page.html", context={})
render(request, address_of_template, context)
# In polls/views.py file
from django.shortcuts import render, HttpResponse
from polls.models import Question

def main_page(request):

	# Fetching list of all questions
	all_questions_qs = Question.objects.all()

	print("Question List successfully fetched!")

	context = {
		'question_list': all_questions_qs,
	}

	return render(request, "polls/main_page.html", context=context)

Django Template Language (DTL)

<!-- In main_page.html file -->
<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<h1>Question List</h1>
	<ul>
		{% for question in question_list %}
			<li>
				{{ question.question_text }} 
				(pub: {{ question.publication_date }})

				<a href="http://127.0.0.1:8000/polls/{{ question.pk }}/details">Details</a>
				<a href="http://127.0.0.1:8000/polls/{{ question.pk }}/results">Results</a>
			</li>
		{% endfor %}
	</ul>
</body>
</html>

Removing Hard-coded URLs

<!-- In main_page.html file -->
<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<h1>Question List</h1>
	<ul>
		{% for question in question_list %}
			<li>
				{{ question.question_text }} 
				(pub: {{ question.publication_date }})

				<a href="{% url "Details" question.pk %}">Details</a>
				<a href="{% url "Results" question.pk %}">Results</a>
			</li>
		{% endfor %}
	</ul>
</body>
</html>

Creating Details Page

# In polls/view.py
from .models import Question, Choice

def details(request, ques_id):

	
	# Fetching quesiton with pk=ques_id
	question_qs = Question.objects.filter(pk=ques_id)
	
	if question_qs:
		question = question_qs[0]
		
		# Fetching choices for this question
		choice_list = Choice.objects.filter(question=question)

		context = {
			"question": question,
			"choice_list": choice_list,
		}

		return render(request, "polls/details.html", context=context)
	else:
		response = "Question with id=" + str(id) + " not found."
		return HttpResponse(response)
<!-- Inside details.html -->
<!DOCTYPE html>
<html>
<head>
	<title>Detail of {{ question.pk }}</title>
</head>
<body>
	<h1>Question Detail</h1>

	<h2>{{ question.question_text }}</h2>
	Pub: {{ question.publication_date }}
	<form method="POST" action="">
		{% for choice in choice_list %}
			<input type="radio" name="choice" id=choice_{{ question.pk }} value={{ question.pk }}>
			<label for=choice_{{ question.pk }}>{{ choice.choice_text }}</label>
		{% endfor %}
		<button type="submit">Vote</button>
	</form>
</body>
</html>
<!-- Inside details.html -->
<form method="POST" action="{% url "Vote" question.pk %}">
<!-- Inside details.html -->
<!DOCTYPE html>
<html>
<head>
	<title>Detail of {{ question.pk }}</title>
</head>
<body>
	<h1>Question Detail</h1>

	<h2>{{ question.question_text }}</h2>
	Pub: {{ question.publication_date }}
	<form method="POST" action="">
		{% csrf_token %}
		{% for choice in choice_list %}
			<input type="radio" name="choice" id=choice_{{ question.pk }} value={{ question.pk }}>
			<label for=choice_{{ question.pk }}>{{ choice.choice_text }}</label>
		{% endfor %}
		<button type="submit">Vote</button>
	</form>
</body>
</html>

Handling the Votes

# In polls/views.py
def vote(request, ques_id):
	print("Voting on question with id=" + str(ques_id))
	print("\n\n")
	print(request)
	print("\n\n")
	print(request.POST)
	response = "Voted successfully on Question with id=" + str(ques_id)
	return HttpResponse(response)
# In polls/views.py
def vote(request, ques_id):
	selected_choice_id = request.POST['choice']

	selected_choice_qs = Choice.objects.filter(pk=selected_choice_id)

	# Checking if choice with id=selected_choice_id exists or not
	if selected_choice_qs:
		selected_choice = selected_choice_qs[0]

		selected_choice.number_of_votes += 1

		selected_choice.save()
	
		response = "Voted successfully on Question with id=" + str(ques_id)
		return HttpResponse(response)
	else:
		response = "Choice with this id is not present."
		return HttpResponse(response)
# In polls/views.py
from django.shortcuts import HttpResponse, HttpResponseRedirect, render
from django.urls import reverse

def vote(request, ques_id):
	selected_choice_id = request.POST['choice']

	selected_choice_qs = Choice.objects.filter(pk=selected_choice_id)

	# Checking if choice with id=selected_choice_id exists or not
	if selected_choice_qs:
		selected_choice = selected_choice_qs[0]

		selected_choice.number_of_votes += 1

		selected_choice.save()
		
		# Printing reverse just to see what is it actually returning
		print(reverse('Results', kwargs={'ques_id': ques_id}))
		
		return HttpResponseRedirect(reverse('Results', kwargs={'ques_id': ques_id}))
	else:
		response = "Choice with this id is not present."
		return HttpResponse(response)

Static files in Django

<!-- In main_page.html file -->
{% load static %}
<!DOCTYPE html>
<html>
<head>
	<title></title>
	<link rel="stylesheet" href={% static "polls/css/style.css" %}>
	<script src={% static "polls/js/main.js" %} defer></script>
</head>
<body>
	<img src="{% static 'polls/images/image.png' %}">
	<h1>Question List</h1>
	<ul>
		{% for question in question_list %}
			<li>
				{{ question.question_text }} 
				(pub: {{ question.publication_date }})

				<a href="{% url "Details" question.pk %}">Details</a>
				<a href="{% url "Results" question.pk %}">Results</a>
			</li>
		{% endfor %}
	</ul>
</body>
</html>

Assignment

Explore Yourself

Content Contributors

Materials