I am creating a simple quiz app using django. When a user submits the answer for a question, the answer is checked using the correct answer present in database.
views.py
from django.shortcuts import render,get_object_or_404
from .models import question
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
def detail(request, question_id):
ques = get_object_or_404(question, pk=question_id)
return render(request, 'detail.html', {'ques': ques})
def index(request):
questions = question.objects.all()
return render(request,"question.html",{"questions":questions})
def vote(request,question_id):
p = get_object_or_404(question, pk=question_id)
selected_choice = p.choice_set.get(pk = request.POST['choice'])
print selected_choice,p.answer_text
if(selected_choice == p.answer_text):
print "yes"
x = int(question_id) + 1
return HttpResponseRedirect(reverse('detail', args=(str(x))))
The vote function is called after user clicks the submit button. The check is performed here. When I print selected_choice and p.answer_text, they show correct values. But when I compare them using equal operator, it doesn't return true even when both are same.
models.py
from django.db import models
class question(models.Model):
question_text = models.CharField(max_length = 400)
answer_text = models.CharField(max_length = 400,default = "name")
def __unicode__(self):
return self.question_text,self.answer_text
class choice(models.Model):
question = models.ForeignKey(question)
choice_text = models.CharField(max_length = 200)
def __unicode__(self):
return self.choice_text
Related
i've been learning Django for these past days and i'm trying to develop an url shortener. It's functional and works great but it misses something: Check if the URL already exists so it can return the short URL stored in db. At this moments it's just checks if the short url is unique and does not exist already, so it always create a new and unique short url for the same URL.
I've tried to use queryset's exists() in if ShortenerForm.objects.filter(url = cleaned_info['url']).exists(): but it always gave me an error object has no attribute 'cleaned_data'
How can i do that?
These are my files:
views.py
from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from utils.shorty.form import ShortenerForm
from shorty.models import Shortener
# Create your views here.
def home(request):
template = "shorty/pages/index.html"
context = {}
context["form"] = ShortenerForm()
if request.method == "GET":
return render(request, template, context)
elif request.method == "POST":
used_form = ShortenerForm(request.POST)
if used_form.is_valid():
shortened_object = used_form.save()
new_url = request.build_absolute_uri("/") + shortened_object.shortcode
long_url = shortened_object.url
context["new_url"] = new_url
context["long_url"] = long_url
return render(request, template, context)
context["errors"] = used_form.errors
return render(request, "shorty/pages/index.html")
def redirect_url_view(request, shortened_path):
try:
shortener = Shortener.objects.get(shortcode=shortened_path)
shortener.redirectCount += 1
shortener.save()
return HttpResponseRedirect(shortener.url)
except:
raise Http404("Sorry this link does not exist")
form.py
from django import forms
from shorty.models import Shortener
class ShortenerForm(forms.ModelForm):
url = forms.URLField(
widget=forms.URLInput(
attrs={"class": "form-control", "placeholder": "Enter URL"}
)
)
class Meta:
model = Shortener
fields = ("url",)
models.py
from django.db import models
from utils.shorty.factory import create_short_url
# Create your models here.
class Shortener(models.Model):
startDate = models.DateTimeField(auto_now_add=True)
lastSeenDate = models.DateTimeField(auto_now=True)
redirectCount = models.PositiveIntegerField(default=0)
url = models.URLField()
shortcode = models.CharField(max_length=6, unique=True, blank=True)
class Meta:
ordering = ["-startDate"]
def __str__(self):
return f"{self.url} to {self.shortcode}"
def save(self, *args, **kwargs):
if not self.shortcode:
self.shortcode = create_short_url(self)
super().save(*args, **kwargs)
Thanks for your patience and time.
I have two models, Question and Solution. One question can have many solutions but a solution can only have one question.
Here they are:
models.py
class Question(models.Model):
question_title = models.CharField(max_length = 100)
question_description = models.TextField()
question_tags = models.TextField()
def __str__(self):
return self.question_title
class Solution(models.Model):
user_profile = models.ForeignKey(UserProfile, on_delete = models.SET_NULL)
question_id = models.ForeignKey(Question, on_delete = models.CASCADE, blank = False, null = True)
solution = models.TextField()
date_modified = models.DateTimeField(auto_now_add = True)
def __str__(self):
return "[SOL] " + self.question_id + "/" + self.user_profile
Here's my views.py:
class QuestionList(generics.GenericAPIView, mixins.ListModelMixin, mixins.CreateModelMixin):
# Used to access all questions and adding one
queryset = Question.objects.all()
serializer_class = QuestionSerializer
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)
class QuestionDetails(generics.GenericAPIView, mixins.RetrieveModelMixin, mixins.UpdateModelMixin,
mixins.DestroyModelMixin):
queryset = Question.objects.all()
serializer_class = QuestionSerializer
lookup_field = 'id'
def get_question(self, id):
try:
return Question.objects.get(id = id)
except Question.DoesNotExist:
raise Http404
def get(self, request, id):
question = self.get_question(id)
serializer = QuestionSerializer(question)
return Response(serializer.data, status.HTTP_200_OK)
def put(self, request, id):
question = self.get_question(id)
serializer = QuestionSerializer(question, data = request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status = status.HTTP_201_CREATED)
return Response(serializer.errors, status = status.HTTP_400_BAD_REQUEST)
def delete(self, request, id):
question = self.get_object(id)
question.delete()
return Response(status = status.HTTP_204_NO_CONTENT)
class SolutionList(generics.GenericAPIView, mixins.ListModelMixin,mixins.CreateModelMixin):
# Empty because I'm still incredibly confused
This is my urlpatterns :
urlpatterns = [
path("questions/", QuestionList.as_view()),
path("questions/<int:id>/", QuestionDetails.as_view()),
]
The first is to access the list of questions and the second is to access a particular question. I want the URL to access the solution list of a particular question to look like this:
questions/question_id/solutions/
where question_id is the ID of the particular question. I also want the URL to access a particular solution of a particular question to look like this:
questions/question_id/solutions/solution_id/
where solution_id is the ID of the particular solution.
How would I do this?
Help is appreciated.
I don't work with mixins but here's the function for you..
def show_solution(request, q_id, s_id):
context = {
'q' : Question.objects.get(pk=q_id),
's' : Solution.objects.filter(question_id=question),
}
return render (request, 'template.html', context)
I am making a quiz application, for result calculation I have written logic ..If the value of answer stored in question model is equal to the answer chosen by user then , when user submits each question , score is incrementing by one, but I've failed to build this logic as am a new user to django please help.
Models.py : question along with its 4 options and the correct answer is in question model(These fields are entered by the user who creates a quiz by filling a form). Answer submitted by user is in answer model(This field is entered by user who takes quiz). score is stored in result model.
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
class quiztitle(models.Model):
Quiz_id = models.AutoField(primary_key=True)
Quiz_title = models.CharField(max_length=600)
User = settings.AUTH_USER_MODEL
User_id= models.ForeignKey(User, on_delete=models.CASCADE)
no_of_ques = models.IntegerField(default=10)
class question(models.Model):
Qid = models.AutoField(primary_key=True)
User = settings.AUTH_USER_MODEL
User_id = models.ForeignKey(User,on_delete=models.CASCADE)
Quiz_id = models.ForeignKey(quiztitle,on_delete=models.CASCADE)
Qques = models.TextField()
Qoption1 = models.TextField()
Qoption2 = models.TextField()
Qoption3 = models.TextField()
Qoption4 = models.TextField()
QAnswer = models.TextField()
class answer(models.Model):
Ansid = models.AutoField(primary_key=True)
Qid = models.ForeignKey(question,on_delete=models.CASCADE)
Quiz_id = models.ForeignKey(quiztitle, on_delete=models.CASCADE)
User = settings.AUTH_USER_MODEL
User_id = models.ForeignKey(User, on_delete=models.CASCADE)
Answer = models.TextField()
class result(models.Model):
result = models.AutoField(primary_key=True)
Quiz_id = models.ForeignKey(quiztitle, on_delete=models.CASCADE)
User_id = models.ForeignKey(User, on_delete=models.CASCADE)
score = models.FloatField()
def __str__(self):
return str(self.pk)
here's views.py file
from django.shortcuts import render,redirect,HttpResponseRedirect
from .models import question ,quiztitle ,answer ,result
from django.contrib.auth.models import User
from .forms import CreateUserForm
from django.contrib import messages
from django.contrib.auth import authenticate,login,logout
from django.contrib.auth.decorators import login_required
from .decorators import unauthenticated_user,allowed_users
from django.contrib.auth.models import Group
def home_page(request):
return render(request,'Home.html')
def forbidden(request):
return render(request,'error403.html')
#unauthenticated_user
def registerPage(request):
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
if form.is_valid():
user = form.save()
username = form.cleaned_data.get('username')
group = Group.objects.get(name='Student')
user.groups.add(group)
messages.success(request, 'account has been created successfully for username' + username)
return redirect('login')
context = {'form':form}
return render(request,'register.html',context)
#unauthenticated_user
def handle_login(request):
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request,user)
if request.user.groups.filter(name="Teacher"):
return redirect('quizmaker')
else:
return redirect('student')
else:
messages.info(request, 'Incorrect Username or Password')
context = {}
return render(request, 'login.html', context)
def logoutUser(request):
logout(request)
return redirect('home')#redirect to login page
#login_required(login_url='home')
#allowed_users(allowed_roles=['Teacher','Head'])
def handle_quiz(request):
if request.method=="POST":
# get post parameters
Quiz_title = request.POST.get('Quiz_title')
Quiz_id = request.POST.get('Quiz_id')
no_of_ques = request.POST.get('no_of_ques')
Qid = request.POST.get('Qid')
Qques = request.POST.get('Qques')
Qoption1 = request.POST.get('Qoption1')
Qoption2 = request.POST.get('Qoption2')
Qoption3 = request.POST.get('Qoption3')
Qoption4 = request.POST.get('Qoption4')
QAnswer = request.POST.get('QAnswer')
title = quiztitle(Quiz_title=Quiz_title,Quiz_id=Quiz_id,no_of_ques=no_of_ques)
title.User_id=request.user
title.save()
detail = question(Qid=Qid,Qques=Qques,Qoption1=Qoption1,Qoption2=Qoption2,Qoption3=Qoption3,Qoption4=Qoption4,QAnswer=QAnswer)
detail.User_id=request.user
detail.Quiz_id = title
detail.save()
messages.success(request,'Your question has been added succesfully')
return HttpResponseRedirect('/quizmaker')
return render(request,"createquiz.html")
#login_required(login_url='login')
#allowed_users(allowed_roles=['Student'])
def handle_response(request):
if request.user.is_authenticated:
myuser = User.objects.all()
title = quiztitle.objects.all()
data = question.objects.all()
if request.method == 'POST':
Answer=request.POST.get('Answer')
response = answer(Answer=Answer)
response.User_id = request.user
response.Quiz_id = request.quiztitle
response.Qid = request.question
Answer.save()
return HttpResponseRedirect('/student')
return render(request,"student.html",context={"messages": data ,"topic": title ,"user1": myuser})
def handle_result(request):
if request.user.is_authenticated:
quiz = quiztitle.objects.all()
ques = question.objects.all()
ans = answer.objects.all()
score = 0
if request.method == 'POST':
while(score<=quiz.no_of_ques):
if (ques.objects.QAnswer == ans.objects.Answer):
score += 1
print(score)
sc = request.POST('score')
res = result(sc=score)
res.User_id = request.user
res.Quiz_id = request.quiztitle
result.save()
return HttpResponseRedirect('/sample')
return render(request, "sample.html", context = {"ques":ques , "ans":ans})
In your handle_result function, you have:
quiz = quiztitle.objects.all()
# ...
while(score<=quiz.no_of_ques):
The issue here is that:
The quiz variable is not ONE quiz, it's ALL of them. So it's not an instance, it's a list of instances (technically, a QuerySet of instances)
Therefore, you cannot call quiz.no_of_ques, because quiz is not an instance
That's why you're getting the 'QuerySet' object has no attribute 'no_of_ques' error. Either query one specific instance, or query them all and loop over them.
In views.py handle_result function,
replacing
quiz = quiztitle.objects.all()
with
quizno = quiztitle.objects.values_list('no_of_ques', flat=True)
#....
while(score<=quizno):
it resolves the error 'QuerySet' object has no attribute 'no_of_ques' as it queries one instance i.e no_of_ques
I have an app for quiz. It shows registered quiz, but when I press submit button, It goes to /quiz/1/do/ to do function in views.py which should do this,
return HttpResponseRedirect(reverse('quiz.views.results', args=(q.id,)))
But it throws an error message,
NoReverseMatch at /quiz/1/do/
Reverse for 'quiz.views.results' not found. 'quiz.views.results' is not a valid view function or pattern name.
I wonder where could be a problem?
Code:
views.py:
from quiz.models import Quiz, Question, Score
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
#login_required()
def index(request):
latest_quiz = Quiz.objects.all().order_by('-created')[:5]
return render_to_response('quiz/index.html', {'latest_quiz': latest_quiz})
def detail(request, quiz_id):
q = get_object_or_404(Quiz, pk=quiz_id)
context = {'quiz': q}
return render(request, 'quiz/detail.html', context)
def results(request, quiz_id):
return HttpResponse("You're looking at the results of quiz %s." % quiz_id)
def do(request, quiz_id):
q = get_object_or_404(Quiz, pk=quiz_id)
try:
answer = ''
for question in q.question_set.all():
answer += request.POST['q%d' % question.id]
except (KeyError, Question.DoesNotExist):
# Redisplaying the form
return render_to_response('quiz/detail.html', {
'quiz': q,
'error_message': "You didn't do the quiz %r " %request.POST,
}, context_instance=RequestContext(request))
else:
s = q.score_set.create(student=request.user.username, submit_answer=answer, score=100)
s.save()
return HttpResponseRedirect(reverse('quiz.views.results', args=(q.id,))) # HERE !!!
def not_found(request, exception=None):
response = render(request, '404.html', {})
response.status_code = 404
return response
def server_error(request, exception=None):
response = render(request, '500.html', {})
response.status_code = 500
return response
urls.py:
from .models import Quiz, Question, Score
from django.urls import path
from . import views as quiz_view
from . views import detail, results, do
from django.contrib.auth.decorators import login_required
app_name = 'quiz'
handler404 = 'quiz.views.not_found'
handler500 = 'quiz.views.server_error'
urlpatterns = [
path('', quiz_view.index, name='detail'),
path('<int:quiz_id>/', quiz_view.detail, name='detail'),
path('<int:quiz_id>/results/', quiz_view.results, name='results'),
path('<int:quiz_id>/do/', quiz_view.do, name='do'),
]
models.py:
from django.db import models
#from django.contrib.auth.models import User
from random import shuffle
class Quiz(models.Model):
""" Quiz model. Every quiz has 10 questions. """
title = models.CharField(max_length=100)
category = models.CharField(max_length=100)
description = models.TextField()
slug = models.SlugField(unique=True)
# author = models.ForeignKey(User, related_name='author')
author = models.CharField(max_length=50)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
class Meta:
verbose_name_plural = 'quizzes'
ordering = ('-modified', 'created')
def __unicode__(self):
return u"%s" % self.title
def options(self):
return list('abcde')
class Question(models.Model):
""" Question model. Each question attached to exact one quiz. """
quiz = models.ForeignKey(Quiz, on_delete=models.PROTECT)
question = models.TextField()
answer = models.TextField()
choice1 = models.TextField()
choice2 = models.TextField()
choice3 = models.TextField()
choice4 = models.TextField()
class Meta:
ordering = ('id', 'question',)
def __unicode__(self):
return u"%s" % self.question
def get_options(self):
return {'answer': self.answer, 'choice1': self.choice1, 'choice2': self.choice2, 'choice3':self.choice3, 'choice4': self.choice4, }
def randomize_options(self):
options = ['answer', 'choice1', 'choice2', 'choice3', 'choice4', ]
shuffle(options)
return options
class Score(models.Model):
""" Score model. Every quiz taken by students are recorded here. """
quiz = models.ForeignKey(Quiz, on_delete=models.PROTECT)
student = models.CharField(max_length=50)
submit_answer = models.CharField(max_length=50)
score = models.IntegerField(default=0)
quiz_taken = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('quiz_taken', 'student', 'score',)
def __unicode__(self):
return u"%s %d" % (student, score)
It return this,
answer
'a'
q
<Quiz: Quiz object (1)>
question
<Question: Question object (1)>
quiz_id
1
request
<WSGIRequest: POST '/quiz/1/do/'>
s
<Score: Score object (4)>
change the line
return HttpResponseRedirect(reverse('quiz.views.results', args=(q.id,)))
to
return HttpResponseRedirect(reverse('quiz:results', args=(q.id,)))
The first argument of reverse must be 'viewname' Django tutorial
If you need to use something similar to the url template tag in your code, Django provides the following function:
reverse(viewname, url conf=None, args=None, kwargs=None, current_app=None)
You must use view name from 'urlpattern':
return HttpResponseRedirect(reverse('quiz:results', args=(q.id,)))
I think you should try this:
return HttpResponseRedirect(reverse('do', args=q.id))
I want to collect the login user's data while using Django. But i don't know how to locate the unique login username when i use django-registration-redux
I have tried to do this, here's my views.py:
from django.shortcuts import render
from yigu.models import Gw, user_data
from django.contrib.auth.models import User
def index(request):
Gw_list = Gw.objects.all()
context_dict = {'cyshici': Gw_list}
return render(request, 'yigu/base.html', context_dict)
def search(request):
if 'gw' in request.GET:
words_1 = request.GET['gw']
result_list = Gw.objects.filter(field_1=words_1)
result_list2 = user_data.objects.filter(word=words_1)
result_list3 = user_data.objects.filter(user=User.username)
# For basic search match and display content
if result_list:
context_dict = {'result_list': result_list}
words = Gw.objects.get(field_1=words_1)
words.views = words.views + 1
words.save()
# For words_information Model
if result_list2 & result_list3:
words2 = user_data.objects.get(word=words_1)
words2.click_times = words2.click_times + 1
words2.save()
else:
words2 = user_data(user=User.username, word=words_1, click_times=words.views)
words2.save()
return render(request, 'yigu/search.html', context_dict)
here's my models.py:
class user_data(models.Model):
user = models.CharField(max_length=255)
word = models.CharField(max_length=255)
click_times = models.IntegerField(default=0)
class Meta:
ordering = ('click_times',)
def __unicode__(self):
return self.user
But the all the username is something like this <class 'django.contrib.auth.models.User'>
Could anyone give me some tips?
User models of using Redux:
from django.contrib.auth.models import User
And add an OneToOneField to user_data:
class UserData(models.Model):
user = models.OneToOneField(User)
clicks = models.IntegerField(default = 0)
def __str__(self):
return self.user.username