Django - Save form fields while paging - django

This will be a lengthy post, please have patience with me, I just started with Django and try to wrap my head around it.
I created a site that will go thru exam questions one at a time, displaying the question and the multiple choice answers like on countless other websites.
The challenge I experience is when the user clicks "NEXT" on the pagination buttons, I would like for the selected answer(option) to be saved back to the database.
I tried it with AJAX scripts but the view never got executed.
Maybe there is a better way to do this or could you please point me into the right direction? I will post all of my code and hope someone can please assist me.
Thank you for taking the time to look at this.
I start with the models.py:
from django.db import models
class QuesModel(models.Model):
question = models.TextField(null=True)
code_snippet = models.TextField(null=True)
op1 = models.CharField(max_length=200,null=True)
op2 = models.CharField(max_length=200,null=True)
op3 = models.CharField(max_length=200,null=True)
op4 = models.CharField(max_length=200,null=True)
ans = models.CharField(max_length=200,null=True)
def __str__(self):
return self.question
class Answer(models.Model):
ans_id = models.AutoField(primary_key=True)
question_id = models.ForeignKey(QuesModel, on_delete=models.CASCADE)
fname = models.CharField(max_length=50)
lname = models.CharField(max_length=50)
examdate = models.DateField(auto_now_add =True)
answer = models.PositiveSmallIntegerField()
def __int__(self):
return QuesModel.question[self.question_id]
template is home.html:
{% extends 'Quiz/dependencies.html' %}
{% block content %}
{% load static %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="container">
<h1>Welcome to my Quiz</h1>
{% for q in page_obj %}
<form method="post" action="{% url 'submit_answers' %}">
{% csrf_token %}
<input type="hidden" name="question_id" value="{{ q.id }}">
<!-- <input type="hidden" name="answer" value="{{ answer }}"> -->
<input type="hidden" name="date" value="{{ default_date }}">
<div class="form-group">
<div class="card text-bg-light mb-0" style="max-width: 50rem;">
<div class="card-header">
<code>
Question {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}<br>
{{q.question}}
</code>
</div>
<div class="card-body">
<class="card-text">
<label for="question">
<pre class="python"><code>{{q.code_snippet|linebreaks|escape}}</code></pre>
</label>
</div>
</div>
<br>
<div class="form-check">
<input class="form-check-input" type="radio" name="{{ q.question }}" id="option1" value="1" data-question-id="{{ q.id }} required>
<label class="form-check-label" for="option1">
{{ q.op1 }}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="{{ q.question }}" id="option2" value="2" data-question-id="{{ q.id }} required>
<label class="form-check-label" for="option2">
{{ q.op2 }}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="{{q.question}}" id="gridRadios1" data-question-id="{{ q.id }} value="3">
<label class="form-check-label" for="gridRadios1">
{{q.op3}}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="{{q.question}}" id="gridRadios2" data-question-id="{{ q.id }} value="4">
<label class="form-check-label" for="gridRadios2">
{{q.op4}}
</label>
</div>
<br>
</div>
</div>
</div>
</div>
{% endfor %}
<div class="container">
<nav aria-label="Page navigation example">
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a>
</li>
{% endif %}
<li class="page-item disabled">
<a class="page-link" tabindex="-1" aria-disabled="true">Question {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</a>
</li>
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="{% url 'home' %}?page={{ page_obj.next_page_number }}" >Next</a>
</li>
{% endif %}
</ul>
</nav>
</div>
<div class="container">
<input id='timer' type='hidden' name="timer" value="">
<br>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
{% block script %}
<script>
const timer=document.getElementById('displaytimer')
console.log(timer.textContent)
const inputtag = document.getElementById('timer')
t=0
setInterval(()=>{
t+=1
timer.innerHTML ="<b>Timer: " +t+" seconds</b>"
inputtag.value = t
},1000)
</script>
{% endblock script %}
</div>
{% endblock %}
Last is the views.py:
from django.shortcuts import redirect,render
from django.contrib.auth import login,logout,authenticate
from .forms import *
from .models import *
from django.http import HttpResponse
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
import datetime
def home(request):
print("HOMEVIEW")
print("REQUEST METHOD=" + request.method) # Debugging line
print("POST=")
print(request.POST) # Debugging line
# Render the question page
if request.method == 'POST':
print("IN POST")
questions=QuesModel.objects.all()
paginator = Paginator(questions, 1)
page_number = request.GET.get('page')
try:
page_obj = paginator.page(page_number)
except PageNotAnInteger:
# If the page is not an integer, show the first page of results
page_obj = paginator.page(1)
except EmptyPage:
# If the page is out of range, show the last page of results
page_obj = paginator.page(paginator.num_pages)
context = {
'page_obj': page_obj,
'answer': request.POST.get('answer'), # define and pass answer to template
}
return render(request,'Quiz/home.html',context)
def save_answer(request):
print("XXXXXXX")
print(request.method) # Debugging line
print(request.POST) # Debugging line
if request.method == 'POST':
# answer = request.POST['answer']
# question_id = request.POST['question_id']
# # Save the answer to the database
# answer = Answer(question_id=question_id, examdate=default_date, answer=answer)
# answer.save()
return HttpResponse('Success')
#Return an error response if the request method is not 'POST'
return HttpResponse('Error: Invalid request method')
def submit_answers(request):
print("submit_answers")
if request.method == 'POST':
print(request.POST)
questions=QuesModel.objects.all()
score=0
wrong=0
correct=0
total=0
incorrect_answers = []
for q in questions:
items = {'op1': q.op1, 'op2': q.op2, 'op3': q.op3, 'op4': q.op4}
total+=1
answer = request.POST.get(q.question) # Gets user’s choice, i.e the key of answer
print(request.POST.get(q.question))
print(q.ans)
print()
if q.ans == request.POST.get(q.question):
score+=10
correct+=1
else:
if q.ans != request.POST.get(q.question):
wrong += 1
testvar=request.POST.get(q.question)
incorrect_answers.append({'question': q.question, 'correct_answer': q.ans, 'user_answer': request.POST.get(q.question) } )
percent = score/(total*10) *100
context = {
'score':score,
'time': request.POST.get('timer'),
'correct':correct,
'wrong':wrong,
'percent':percent,
'total':total,
'incorrect_answers': incorrect_answers, # pass list to template
}
return render(request,'Quiz/result.html',context)
def default_date():
return datetime.datetime.now()
def pageme(request):
print("pageme_here")
questions = QuesModel.objects.all()
paginator = Paginator(questions, 1)
page_number = request.GET.get('page')
try:
page_obj = paginator.page(page_number)
except PageNotAnInteger:
page_obj = paginator.page(1)
except EmptyPage:
page_obj = paginator.page(paginator.num_pages)
context = {
'page_obj': page_obj,
}
return render(request, 'Quiz/pageme.html', context)
def saveme(request):
# Perform some actions here, such as saving data to the database
print("saveme_here") # Debug statement
return HttpResponse("Save successful") # Return a response to the client
# def save_answer(request):
# if request.method == 'POST':
# answer = request.POST['answer']
# question_id = request.POST['question_id']
# # Save the answer to the database
# answer = Answer(question_id=question_id, examdate=default_date, answer=answer)
# answer.save()
# return HttpResponse('Success')
# return HttpResponse('Error')
# def home(request):
# if request.method == 'POST':
# print(request.POST)
# questions=QuesModel.objects.all()
# #answer
# answer = request.POST.get('answer')
# question_id = request.POST.get('question_id')
# examdate = request.POST.get('date')
# answer = Answer(question_id=question_id, examdate=examdate, answer=answer)
# answer.save()
# #end answer
# score=0
# wrong=0
# correct=0
# total=0
# incorrect_answers = []
# for q in questions:
# items = {'op1': q.op1, 'op2': q.op2, 'op3': q.op3, 'op4': q.op4}
# total+=1
# answer = request.POST.get(q.question) # Gets user’s choice, i.e the key of answer
# print(request.POST.get(q.question))
# print(q.ans)
# print()
# if q.ans == request.POST.get(q.question):
# score+=10
# correct+=1
# else:
# if q.ans != request.POST.get(q.question):
# wrong += 1
# testvar=request.POST.get(q.question)
# incorrect_answers.append({'question': q.question, 'correct_answer': q.ans, 'user_answer': request.POST.get(q.question) } )
# percent = score/(total*10) *100
# context = {
# 'score':score,
# 'time': request.POST.get('timer'),
# 'correct':correct,
# 'wrong':wrong,
# 'percent':percent,
# 'total':total,
# 'incorrect_answers': incorrect_answers, # pass list to template
# }
# return render(request,'Quiz/result.html',context)
# else:
# questions=QuesModel.objects.all()
# paginator = Paginator(questions, 1)
# page_number = request.GET.get('page')
# try:
# page_obj = paginator.page(page_number)
# except PageNotAnInteger:
# page_obj = paginator.page(1)
# except EmptyPage:
# page_obj = paginator.page(paginator.num_pages)
# context = {
# 'page_obj': page_obj,
# }
# return render(request,'Quiz/home.html',context)
def addQuestion(request):
if request.user.is_staff:
form=addQuestionform()
if(request.method=='POST'):
form=addQuestionform(request.POST)
if(form.is_valid()):
form.save()
return redirect('/')
context={'form':form}
return render(request,'Quiz/addQuestion.html',context)
else:
return redirect('home')
def registerPage(request):
if request.user.is_authenticated:
return redirect('home')
else:
form = createuserform()
if request.method=='POST':
form = createuserform(request.POST)
if form.is_valid() :
user=form.save()
return redirect('login')
context={
'form':form,
}
return render(request,'Quiz/register.html',context)
def loginPage(request):
if request.user.is_authenticated:
return redirect('home')
else:
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)
return redirect('/')
context={}
return render(request,'Quiz/login.html',context)
def logoutPage(request):
logout(request)
return redirect('/')
Please excuse this messy code, I tried all kinds of things and now I hope I can finish it with your help.

Here, I have tried to change your code and made some changes.
models.py
from django.db import models
class QuesModel(models.Model):
question = models.TextField(null=True)
code_snippet = models.TextField(null=True)
op1 = models.CharField(max_length=200,null=True)
op2 = models.CharField(max_length=200,null=True)
op3 = models.CharField(max_length=200,null=True)
op4 = models.CharField(max_length=200,null=True)
ans = models.CharField(max_length=200,null=True)
def __str__(self):
return self.question
class Answer(models.Model):
ques = models.ForeignKey(QuesModel, on_delete=models.CASCADE)
fname = models.CharField(max_length=50)
lname = models.CharField(max_length=50)
examdate = models.DateField(auto_now_add =True)
answer = models.CharField(max_length=200,null=True)
def __int__(self):
return self.ques__question
Note: Django provides a default "id" field for each model so no need for ans_id and in the Answer model 'question' field is updated with alias 'ques'
Then go to your command line and execute commands
python manage.py makemigrations
python manage.py migrate
Add some questions and answers
views.py
from django.contrib.auth import login,logout,authenticate
from .forms import *
from .models import *
from django.http import HttpResponse, JsonResponse
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
import datetime
import json
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render, redirect
# here Disabling CSRF protection for this view function
#csrf_exempt
def home(request):
if request.method == "GET":
questions=QuesModel.objects.all()
paginator = Paginator(questions, 1)
page_number = request.GET.get('page')
try:
page_obj = paginator.get_page(page_number)
except PageNotAnInteger:
page_obj = paginator.page(1)
except EmptyPage:
page_obj = paginator.page(paginator.num_pages)
context = {
'page_obj': page_obj,
'default_date': default_date
}
return render(request,'Quiz/home.html',context)
# Render the question page
if request.method == 'POST':
parse_json = json.loads(request.body)
for k,v in parse_json.items():
ques = QuesModel.objects.get(id=int(k))
answer = v
obj, created = Answer.objects.update_or_create(
ques=ques, answer=answer,
defaults={'answer': answer, 'examdate': default_date, 'fname': "Bhavesh", "lname": "Patil"})
return redirect('get-results')
# GET Result Page
def get_result(request):
score=0
wrong=0
correct=0
total= (QuesModel.objects.all().count()) * 10
# Note you have to map user here I am keeping user static with fname -> Bhavesh and lname -> Patil ... Its me
get_answers = Answer.objects.filter(fname='Bhavesh', lname='Patil')
for i in get_answers:
if i.answer == i.ques.ans:
score += 10
correct += 1
else:
wrong += 1
percentage = score/total*100
context = {'percent': round(percentage,2), 'correct':correct, 'wrong': wrong, 'total':total, 'score': score}
return render(request, 'Quiz/results.html', context)
def default_date():
return datetime.datetime.now()
def addQuestion(request):
if request.user.is_staff:
form=addQuestionform()
if request.method=='POST':
form=addQuestionform(request.POST)
if form.is_valid():
form.save()
return redirect('/')
context={'form':form}
return render(request,'Quiz/addQuestion.html',context)
else:
return redirect('home')
def registerPage(request):
if request.user.is_authenticated:
return redirect('home')
else:
form = createuserform()
if request.method=='POST':
form = createuserform(request.POST)
if form.is_valid() :
user=form.save()
return redirect('login')
context={
'form':form,
}
return render(request,'Quiz/register.html',context)
def loginPage(request):
if request.user.is_authenticated:
return redirect('home')
else:
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)
return redirect('/')
context={}
return render(request,'Quiz/login.html',context)
def logoutPage(request):
logout(request)
return redirect('/')
Note: Be careful while copying the code ... it may give Indentation error so check that as well
Now just replace your home template with this home.html
(here, I didn't have any idea of 'dependencies.html' so I haven't extended that so I have created home.html and results.html )
add below two templates in folder "Quiz". Quiz will have this templates
Quiz |--- home.html
|--- results.html
|--- dependencies.html
|--- ...
home.html
{% comment %}<!-- {% extends 'Quiz/dependencies.html' %} --> {% endcomment %}
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
{% block content %}
{% load static %}
<div class="container">
<h1>Welcome to my Quiz</h1>
{% for q in page_obj %}
<form>
<input type="hidden" name="question_id" value="{{ q.id }}" id="questionID">
<!-- <input type="hidden" name="answer" value="{{ answer }}"> -->
<input type="hidden" name="date" value="{{ default_date }}">
<div class="form-group">
<div class="card text-bg-light mb-0" style="max-width: 50rem;">
<div class="card-header">
<code>
Question {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}<br>
{{q.question}}
</code>
</div>
<div class="card-body">
<class="card-text">
<label for="question">
<pre class="python"><code>{{q.code_snippet|linebreaks|escape}}</code></pre>
</label>
</div>
</div>
<br>
<div>
<div class="form-check">
<input class="form-check-input" type="radio" name="question" id="option1" value="{{ q.op1 }}" data-question-id="{{ q.id }}" onchange="submitValue(this)">
<label class="form-check-label" for="option1">
{{ q.op1 }}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="question" id="option2" value="{{ q.op2 }}"" data-question-id="{{ q.id }}" onchange="submitValue(this)">
<label class="form-check-label" for="option2" >
{{ q.op2 }}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="question" id="option3" data-question-id="{{ q.id }}" value="{{ q.op3 }}" onchange="submitValue(this)">
<label class="form-check-label" for="option3" >
{{q.op3}}
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="question" id="option4" data-question-id="{{ q.id }}" value="{{ q.op4 }}" onchange="submitValue(this)">
<label class="form-check-label" for="option4">
{{q.op4}}
</label>
</div>
</div>
<br>
</div>
</div>
</div>
</div>
{% endfor %}
<div class="container">
<nav aria-label="Page navigation example">
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a>
</li>
{% endif %}
<li class="page-item disabled">
<a class="page-link" tabindex="-1" aria-disabled="true">Question {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}</a>
</li>
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="{% url 'home' %}?page={{ page_obj.next_page_number }}" >Next</a>
</li>
{% endif %}
</ul>
</nav>
</div>
<div class="container">
<input id='timer' type='hidden' name="timer" value="">
<br>
<button type="submit" onclick="submitResult()" class="btn btn-primary">Submit</button>
</div>
</form>
{% block script %}
<script>
const timer=document.getElementById('displaytimer')
console.log(timer.textContent)
const inputtag = document.getElementById('timer')
t=0
setInterval(()=>{
t+=1
timer.innerHTML ="<b>Timer: " +t+" seconds</b>"
inputtag.value = t
},1000)
</script>
{% endblock script %}
</div>
{% endblock %}
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script>
// this function will store user choose answer in session storage
// you can see this storage -> just google it "how to see session storage in browser?"
function submitValue(ele){
var questionID = document.getElementById('questionID').value
var answer = ele.value
sessionStorage.setItem(questionID, answer);
}
</script>
<script>
// this script will keep track of user activity i.e retrive user answers from session storage. ie if you move to previous or next page user's choosed answers will be displayed.
$(window).on('load', function(){
console.log(sessionStorage)
var questionID = document.getElementById('questionID').value
var arrayElements = document.getElementsByClassName('form-check-input')
if (sessionStorage.length){
var value = sessionStorage.getItem(questionID)
// console.log(arrayElements)
const ele = Array.prototype.filter.call(arrayElements, (ele) => ele.value == value)
console.log(ele)
if (ele.length > 0){
ele[0].checked = true;
}
}
});
</script>
<script>
// this function will send user result to server and redirect to result page
function submitResult(){
fetch("{% url 'home' %}", {
method: "POST",
body: JSON.stringify(sessionStorage),
headers: {
"Content-type": "text/html; charset=UTF-8"
}
}).then((response) => {
window.location.replace("{% url 'get-results' %}");
sessionStorage.clear();
});
}
</script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.14.7/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
Next step, Add results.html to quiz
results.html
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<title>Results</title>
</head>
<body>
<div class="m-4">
<table class="table table-bordered">
<thead>
<tr>
<th colspan="2">Result</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Wrong Answers</th>
<td>{{wrong}}</td>
</tr>
<tr>
<th scope="row">Correct Answers</th>
<td>{{correct}}</td>
</tr>
<tr>
<th scope="row">Total Score</th>
<td>{{score}} / <span><b>{{total}}</b></span></td>
</tr>
<tr>
<th scope="row">Percentage</th>
<td>{{percent}} %</td>
</tr>
</tbody>
</table>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.14.7/dist/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
Note: : Here you can customize above template...I kept it simple and focused on your problem statement
Final step is route urls,
urls.py
from django.contrib import admin
from django.urls import path
from .views import *
urlpatterns = [
path('admin/', admin.site.urls),
path('', home, name='home'),
path('get-result/', get_result, name='get-results'),
# ... your url routes
]
This all took my day so please verify and let me know whether this solves your problem or not...
Thank You

Related

Slug returns Reverse for '' with arguments '('',)' not found. 1 pattern(s)

I am trying to make it so when I view a blog from any particular link on my website, the url displays www.example.com/view-blog/slug. I have got it working for my images and image title. But I cannot get it to work with blog titles.
It keeps returning the error:
Reverse for 'viewblog' with arguments '('',)' not found. 1 pattern(s) tried: ['view\-blog/(?P[-a-zA-Z0-9_]+)/\Z'].
Models.py
class BlogPost(models.Model):
blog_title = models.CharField(max_length=100, null=False, blank=False, default="")
slug = models.SlugField()
blog_article = RichTextUploadingField(null=True, blank=True, default="ici")
blog_image = models.ImageField(null=True, blank=True, upload_to="images", default="default.png")
blog_date = models.DateField(auto_now_add=True)
blog_published = models.BooleanField(default=False)
blog_featured = models.BooleanField(default=False)
def save(self, *args, **kwargs):
self.slug = self.slug or slugify(self.blog_title)
super().save(*args, **kwargs)
def __str__(self):
return self.blog_title
Views.py EDIT: ADDED ALL VIEWS.
def blogPage(request):
posts = BlogPost.objects.filter(blog_date__lte=timezone.now()).order_by('-blog_date')[:4]
context = {'posts': posts}
return render(request, 'blog.html', context)
def blogsPage(request):
posts = BlogPost.objects.filter(blog_date__lte=timezone.now()).order_by('-blog_date')
context = {'posts': posts}
return render(request, 'blogs.html', context)
def searchBlogs(request):
if request.method == "POST":
searched = request.POST.get('searched', False);
searched_blogs = BlogPost.objects.filter(blog_title__icontains=searched)
return render(request, 'search-blogs.html', {'searched': searched, 'searched_blogs': searched_blogs})
def viewBlog(request, slug):
try:
blog = BlogPost.objects.get(slug=slug)
except BlogPost.DoesNotExist:
print("ViewBlog with this slug does not exist")
blog = None
return render(request, 'view-blog.html', {'blog': blog, 'slug': slug})
Urls.py
urlpatterns = [
path('', views.galleryPage, name='gallery'),
path('gallery/', views.galleryPage, name='gallery'),
path('contact/', views.contactPage, name='contact'),
path('blog/', views.blogPage, name='blog'),
path('blogs/', views.blogsPage, name='blogs'),
path('search-blogs/', views.searchBlogs, name='searchblogs'),
path('view-image/<slug:slug>/', views.viewImage, name='viewimage'),
path('view-blog/<slug:slug>/', views.viewBlog, name='viewblog'),
path('thank-you/', views.thankyouPage, name='thankyou'),
path('about-me/', views.aboutmePage, name='aboutme'),
]
**One of my templates I wish to link to viewblog page from ** ( I have tried to replace .id on my urls with .slug but this is what gives me the error.
<body>
<header>{% include 'navbardesktop.html' %}</header>
<div class="blog-container">
<h1 class="all-blog-title" id="all-blog-title" style="text-align: center;">All Blogs</h1>
<br>
<div class="search">
<form class="d-flex" method="POST" action="{% url 'searchblogs' %}">
{% csrf_token %}
<i class="fa fa-search"></i>
<input type="text" class="form-control" placeholder="Search keyword" name="searched">
<button id="search-btn" class="btn btn-secondary">Search</button>
</form>
</div>
<br>
<hr id="blog-hr" style="width:50%; margin-left:25% !important; margin-right:25% !important;" />
<div class="blog-post-container">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Blog List
</button>
<ul class="dropdown-menu" style="background-color: #d6d6d6 ;">
{% for post in posts %} {% if post.blog_published is True %}
<li><a class="dropdown-item" href="{% url 'viewblog' post.id %}">{{post.blog_title}}</a></li>
{% endif %}
{% endfor %}
</ul>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
</div>
<div class="row">
{% for post in posts %} {% if post.blog_published is True %}
<div class="col-md-4" id="blog-col">
<div class="blog-post">
<div class="blog-content">
<img class="blog-img"src="{{post.blog_image.url}}"alt="My image"/>
<h2 class="blog-title">{{post.blog_title}}</h2>
<hr id="blog-hr" style="width: 90%" />
<article class="blog-article">
<p>{{post.blog_article|truncatechars_html:265|safe}}</p>
</article>
Read More...
<p class="blog-date">Posted on: {{post.blog_date}}</p>
</div>
</div>
</div>
{% endif %} {% empty %}
<h3>No Blog Uploads</h3>
{% endfor %}
</div>
</div>
</div>
</div>
the error message
Reverse for 'viewblog' with arguments '('',)' not found.
Remark: what is '('',)' ??
it is simply the print of a python list () with one empty argument ('',). The comma just indicates it is a list. This is placed in '' to structure the error message text '('',)'
so this is the list of arguments that is extracted from your {% url .... %} statement for the error message
always means you have and url tag pointing to "viewblog" that requires an argument (because definded like that in urlpatterns in urls.py ) but actually one of them is null or "" (which is not accepted to reverse a valid url):
urlpatterns = [
...
path('view-blog/<slug:slug>/', views.viewBlog, name='viewblog'),
...
]
---------------------------------
href="{% url 'viewblog' post.id %}"
Now in your case you had originally post.id as parameter (I understood you changed that to post.slug). That means one of the post database entries has a post.slug that is null or ""
to debug just print the value of post.slug into the html page and you will see what is wrong. the "xxx" and "yyy" are there to mark on the output clearly where some content shoult appear (because without it is more difficult to see if there is an empty output).
{% for post in posts %}
xxx {{ post.slug }} xxx <br>
yyy {{ post.blog_title }} xxx <br>
{% endfor %}
Another way of checking post.slug is to go to the admin page ouf your app and inspect the database entries directly
And a third one would be to print the query result for posts in the view:
def blogsPage(request):
posts = BlogPost.objects.filter(blog_date__lte=timezone.now()).order_by('-blog_date')
context = {'posts': posts}
for post in posts:
print(post)
return render(request, 'blogs.html', context)
which will show the content of posts in the console

Error ! Please! Make sure all fields are entered and valid

Have been trying to use Django forms for contact tab - but getting the - Error ! Please! Make sure all fields are entered and valid.
**forms.py **
from django import forms
from content.models import Contact
class ContactForm(forms.ModelForm):
fullname = forms.CharField(required=True,max_length=100)
email = forms.EmailField(required=True,max_length=100)
subject = forms.CharField(required=True,max_length=300)
phone_number = forms.CharField(required=True,max_length=100)
message = forms.CharField(required=True,widget=forms.Textarea)
class Meta:
model = Contact
fields = [
'fullname',
'email',
'subject',
'message',
'phone_number',
]
def __init__(self, *args, **kwargs):
super(ContactForm, self).__init__(*args, **kwargs)
self.fields['fullname'].widget.attrs['placeholder'] = 'Your FullName'
self.fields['fullname'].widget.attrs['class'] = 'form-control form-control-lg'
self.fields['email'].widget.attrs['placeholder'] = 'Your Email'
self.fields['email'].widget.attrs['class'] = 'form-control form-control-sm'
self.fields['subject'].widget.attrs['placeholder'] = 'Subject'
self.fields['subject'].widget.attrs['class'] = 'form-control form-control-sm'
self.fields['phone_number'].widget.attrs['placeholder'] = 'Your Phone Number'
self.fields['phone_number'].widget.attrs['class'] = 'form-control'
self.fields['message'].widget.attrs['placeholder'] = 'Your Message'
self.fields['message'].widget.attrs['cols'] = '30'
self.fields['message'].widget.attrs['rows'] = '10'
views.py
from email.message import EmailMessage
from django.shortcuts import render
from content.forms import ContactForm
from content.models import About, Profile,Primaryskill,Secondaryskill,Services,Portfolio,Blog,Testimonial,Contact
from django.contrib import messages
#for sending emails and contact
from django.http import HttpResponseRedirect
from django.core.mail import send_mail
from django.conf import settings
from django.template.loader import render_to_string
from django.template import loader
# Create your views here.
def Homepage(request):
#django orm concept
profile = Profile.objects.first() #this will fetch all the data from Profile table first row and store it in profile
about = About.objects.first()
primaryskill = Primaryskill.objects.all()
secondaryskill = Secondaryskill.objects.all()
services = Services.objects.all()
testimonials = Testimonial.objects.all()
form = ContactForm()
context = {
'profile':profile,
'about': about,
'primaryskill':primaryskill,
'secondaryskill':secondaryskill,
'services':services,
'testimonials':testimonials,
'form':form,
}
return render(request,"index.html",context)
def MailContact(request):
if request.method == "POST":
form = ContactForm(request.POST)
if form.is_valid():
data = Contact()
data.fullname = form.cleaned_data['fullname']
data.email = form.cleaned_data['email']
data.subject = form.cleaned_data['subject']
data.phone_number = form.cleaned_data['phone_number']
data.message = form.cleaned_data['message']
data.save()
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
fullname = form.cleaned_data['fullname']
phone_number = form.cleaned_data['phone_number']
email = form.cleaned_data['email']
email_from = settings.EMAIL_HOST_USER
recipient_list = ['abc#gmail.com',]
html_message = loader.render_to_string(
'email.html',
{
'subject':subject,
'message':message,
'fullname':fullname,
'email':email,
'phone_number':phone_number,
}
)
if subject and message and email_from and recipient_list and html_message:
try:
send_mail(subject, message, email_from, recipient_list, html_message = html_message, fail_silently=False)
except:
messages.error(request,"Cannot send mail right now, Try again later")
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
messages.success(request,"Message sent successfully")
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
else:
messages.error(request,"Please! Make sure all fields are entered and valid.")
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
else:
messages.error(request,"Please! Make sure all fields are entered and valid.")
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
contact.html
<div data-aos="fade-left" data-aos-duration="500" data-aos-delay="200" data-aos-once="true" class="rn-contact-area section-height">
<div class="inner">
<h5 class="title">
Contact With Me
</h5>
{% if messages %}
{% for message in messages %}
<div id="index-alert"
class="alert {% if message.tags %}alert-{{ message.tags }}{% endif %} alert-dismissible bg-{% if message.tags == 'success' %}success{% elif message.tags == 'danger' %}danger{% elif message.tags == 'primary' %}primary{% endif %}">
×
<strong class="text-white"> {% if message.tags == 'success' %}Success{% elif message.tags == 'danger' %} Error {% elif message.tags == 'primary' %}Message{% endif %} ! </strong><span class="text-white">{{message}}</span>
</div>
{% endfor %}
{% endif %}
<!--
<script>
window.setTimeout(function () {
$("#index-alert").fadeTo(800, 0).slideUp(800, function () {
$(this).remove();
});
}, 2000);
</script>
-->
<!-- Form area Srart -->
<form action = "{% url 'Contact' %}" method = "POST">
{% csrf_token %}
<div class="contact-form-wrapper">
<div class="introduce">
<div class="row">
<div class="col-lg-12 col-xl-6">
<div class="form-group">
<label for="name">Your Name</label>
{{form.fullname}}
</div>
</div>
<div class="col-lg-12 col-xl-6">
<div class="form-group">
<label for="phone">Phone Number</label>
{{form.phone_number}}
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label for="email">Email</label>
{{form.email}}
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label for="subject">subject</label>
{{form.subject}}
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<label for="message">Your Message</label>
{{form.message}}
</div>
</div>
<div class="col-lg-12">
<button class="rn-btn" type="submit">
<span>SEND MESSAGE</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-right">
<line x1="5" y1="12" x2="19" y2="12"></line>
<polyline points="12 5 19 12 12 19"></polyline>
</svg>
</button>
</div>
</div>
</div>
</div></form?
<! --Form area End -->
</div>
</div>
email.html
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Email</title>
</head>
<body>
<h1>Hi - this is contact form message</h1>
<p>
{{fullname}}
{{phone_number}}
{{email}}
{{subject}}
{{message}}
</p>
</body>
</html>
The HTML code is displaying so - I think it's working fine and I tried several different values again and again but it is not validating.
Thank you so much for helping!!

Form wont appear in admin side of website and confused as to why and wondering if someone else could see why

models.py
class Contact(models.Model):
BookID = models.CharField(max_length=30)
BookTitle = models.CharField(max_length=30)
Author = models.CharField(max_length=35)
UploadImage =
models.ImageField(upload_to='ContactImg')
def __str__(self):
return self.BookId
forms.py
class ContactForm(forms.Form):
BookID=forms.CharField(max_length=30,required=True)
BookTitle=forms.CharField(max_length=30,required=True)
Author=forms.CharField(max_length=35,required=True)
UploadImage=forms.ImageField()
class Meta:
model = Contact
fields = ('BookID', 'BookTitle', 'Author','UploadImage')
Views.py
def ContactUs(request):
context_dict = {}
if request.user.is_authenticated:
context_dict['logged_in'] = True
else:
context_dict['logged_in'] = False
user_form=ContactForm()
if request.method == 'POST':
user_form = ContactForm(request.POST)
if user_form.is_valid():
# we load our profile instance
Contact.BookId = user_form.get('BookId')
Contact.BookTitle = user_form.get('BookTitle')
Contact.Author= user_form.get('Author')
Contact.UploadImage= user_form.get('UploadImage')
Contact.save()
return redirect('readingTime:home')
else:
# Invalid form
# messages.error(request, 'Form contains errors. Double check')
print(user_form.errors)
messages.error(request, 'Form contains errors. Double check')
# user_form = user_form.errors
# user_form = RegisterForm()
else:
# Blank form since we do not have an HTTP POST
user_form = ContactForm()
return render(request,"readingTime/ContactUs.html",context=context_dict)
Html
{% extends 'readingTime/base.html' %}
{% load staticfiles %}
{% block style_css %}
<link rel="stylesheet" type="text/css" href="{% static 'css/ContactUs.css' %}"
xmlns="http://www.w3.org/1999/html"/>
{% endblock %}
{% block navigation_bar %}
<div class="navigation-bar">
home
{% if logged_in %}
Sign Out
My account
User Polls
{% else %}
Register
Sign In
Poll Results
{% endif %}
</div>
{% endblock %}
{% block body_block %}
<div class="main" >
<h1>Contact Us</h1>
<div class="main2">
<form id="user_form" class="contact-form" method="post" action="{% url 'readingTime:ContactUs'
%}" enctype="multipart/form-data">
<div class="contact-container">
<h2>Request To Add A Book</h2>
{% csrf_token %}
Bookd Id (ISBN) <input type="text" name="BookID" value="" size="30" />
<br />
Book Title <input type="text" name="BookTitle" value="" size="50" />
<br />
Author(Full Name) <input type="text" name="Author" value="" size="30" />
<br />
Book Cover(Optional)<input type="file" id="UploadImage" name="UploadImage">
<br/>
<!-- Submit button-->
<div>
<button type="submit" class="submit-button">Send Request</button>
</div>
</div>
</form>
<h4>Popular Questions</h4>
<ul>
<li> <div class="Question">How To Sign In ?</br></br>
<Answer>Click on the sign in page button and enter your log in details</Answer></div>
</li>
</br></br></br>
<li> <div class="Question">How to edit my profile?</br></br>You need to be first signed in and then you can navigate to myAccount and click edit profile to change your details</br></div></li>
</br></br></br>
<li> <div class="Question">How to Sign out of my account?</br></br>You need to navigate to the sign out button at the top and press it to sign out</div></li>
</br></br></br>
<li> <div class="Question">How to register for an account?</br></br>Click on the register button at the top of the page in order and then enter your details or go to the sign in page and sign up to register there</div></li></ul>
<!-- action indicates where to send the form when submitted -->
</div>
</div>
{% endblock %}
{% block footer %}
{% endblock %}
I am wondering as to why it wont let me send the information inside the form to admin side of the page as it lets me automaticaly a manual from into the admin side but wont let me recieve the data from the form i create for the contact us page and was wondering if anyone has any ideas as to why this is ?
The way you have done this has a lot of errors.
Lets start again:
Your model looks fine.
forms.py:
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = '__all__'
views.py
from .forms import ContactForm
def ContactUs(request):
if request.user.is_authenticated:
logged_in = True
else:
logged_in = False
if request.method == 'GET':
user_form=ContactForm()
elif request.method == 'POST':
user_form = ContactForm(request.POST)
if user_form.is_valid():
user_form.save()
return redirect('readingTime:home')
context = {
'logged_in': logged_in,
'user_form': user_form
}
return render(request, "readingTime.html", context)
readingTime.html
<form id="user_form" class="contact-form" method="POST" action="{% url'readingTime:ContactUs'%}" enctype="multipart/form-data">
<div class="contact-container">
<h2>Request To Add A Book</h2>
{% csrf_token %}
{{ user_form }}
<!-- Submit button-->
<div>
<button type="submit" class="submit-button">Send Request</button>
</div>
</div>

Template Tag not working with csrf_token

I am attempting to create a custom template tag to display a comment. When I try submitting a reply through the form attached to each comment, I get an error:
Forbidden (403)
CSRF verification failed. Request aborted.
Reason given for failure:
CSRF token missing or incorrect.
The csrf token works on the form with the download and follow button, but not on the form generated from the template tag. Any help would be appreciated.
DocumentView
def DocumentView(request, doc_id):
context = {}
user = None
if request.user.is_authenticated():
email = request.user.email
id = request.user.id
user = get_user_information(email=email)
else:
user = None
context['user'] = user
if request.method == 'POST':
user_id = request.POST.get('submit', '')
doc = Doc.objects.get(id=doc_id)
doc_version = DocVersion.objects.filter(doc__id=doc_id).latest('id')
doc_title = doc.response_title
allow_comments = doc.allow_comments
comments = {}
if user['user_type'] == 'DA':
for comment in Comment.objects.filter(doc_id=doc_id):
comments[comment.id] = {'content': comment.content, 'reply_to': comment.reply_to, 'user_id': comment.user.id}
else:
for comment in Comment.objects.filter(doc_id=doc_id, is_flagged=False):
comments[comment.id] = {'content': comment.content, 'reply_to': comment.reply_to, 'user_id': comment.user.id}
context['comments'] = comments
context['allow_comments'] = allow_comments
context['doc_title'] = doc_title
print context
return render(request, 'doc/document.html', context)
comment_tags.py
from django.template import Library, Node, Context, Variable
from django.template.loader import get_template
from django import template
register = Library()
#register.tag()
def comments(parser, token):
user_id, profile_pic, reply_id, comment_id, content, info = None, None, None, None, "", ""
for index, x in enumerate(token.split_contents()):
if x == 'user_id':
user_id = token.split_contents()[index + 1]
if x == 'profile_pic':
profile_pic = token.split_contents()[index + 1]
if x == 'content':
content = token.split_contents()[index + 1]
if x == 'info':
info = token.split_contents()[index + 1]
if x == 'reply_id':
reply_id = token.split_contents()[index + 1]
if x == 'comment_id':
comment_id = token.split_contents()[index + 1]
return CommentNode(user_id, profile_pic, comment_id, content, info, reply_id)
class CommentNode(template.Node):
def __init__(self, user_id, profile_pic, comment_id, content, info, reply_id):
self.user_id = template.Variable(user_id)
self.profile_pic = template.Variable(profile_pic)
self.content = template.Variable(content)
self.info = template.Variable(info)
self.comment_id = template.Variable(comment_id)
if reply_id != None:
self.reply_id = template.Variable(reply_id)
else:
self.reply_id = reply_id
def render(self, context):
t = get_template("srd/comment.html")
if self.reply_id == None:
return t.render({
'user_id': self.user_id.resolve(context),
'profile_pic': self.profile_pic.resolve(context),
'comment_id': self.comment_id.resolve(context),
'content': self.content.resolve(context),
'info': self.info.resolve(context),
'reply_id': self.reply_id
}
)
else:
return t.render({
'user_id': self.user_id.resolve(context),
'profile_pic': self.profile_pic.resolve(context),
'comment_id': self.comment_id.resolve(context),
'content': self.content.resolve(context),
'info': self.info.resolve(context),
'reply_id': self.reply_id.resolve(context)
})
document.html
{% load static %}
{% load comment_tags %}
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ doc_title }}</title>
<link rel="stylesheet" type="text/css" href="{% static "stylesheets/doc.css" %}">
<script src="{% static "javascript/jquery-3.2.1.min.js" %}" type="text/javascript"></script>
<script src="{% static "javascript/doc.js" %}" type="text/javascript"></script>
</head>
<body>
<div class="main_div">
<div class="content_div">
<div class="info_div">
<h2>[{{ generic_name }}]</h2>
<label>{{ doc_title }} [Edit]</label>
</div>
<div class="doc_div">
<div class="doc_preview">
</div>
<div class="doc_preview_info">
<form method="post">
{% csrf_token %}
<input type="hidden" value="{{ user.id }}" />
<input type="submit" value="Donwload PDF" /><br/>
<input type="submit" value="Follow" />
</form>
</div>
</div>
{% if allow_comments %}
<div class="comment_div" id="comment_div">
{% for commentid, comment in comments.items %}
{% if comment.reply_to %}
{% comments comment_id commentid user_id comment.user_id reply_id comment.reply_to.id profile_pic "hi" content comment.content info "XYZ" %}
{% else %}
{% comments comment_id commentid user_id comment.user_id profile_pic "hi" content comment.content info "XYZ" %}
{% endif %}
{% endfor %}
</div>
{% endif %}
</div>
<div class="ad_div">
<div class="ad"></div>
<div class="ad"></div>
<div class="ad"></div>
<div class="ad"></div>
</div>
</div>
</body>
</html>
comment.html
<div class="comment">
<div class="profile_pic">
{{ user_id }}
</div>
<div class="comment_content">
<div class="top_bar">
<div class="comment_info">
{{ info }}
</div>
<div class="flag">
Flag
</div>
</div>
<div class="comment_text">
{{ content }}
</div>
<div class="reply_bar">
<a id="reply_link_{{ comment_id }}" class="reply_link" href="#">Reply</a>
</div>
</div>
</div>
<div class="reply" id="reply_{{ comment_id }}">
<form method="post">
{% csrf_token %}
<input type="hidden" value="{{ reply_id }}"/>
<input name="reply_text" type="text" />
<input type="submit" value="Post" />
</form>
</div>
Since you are rendering the template manually in your tag, you need to use a RequestContext so that it runs the context processors - including the one that adds the CSRF token.
return t.render(RequestContext(context['request'], {
...
}))
Note, the whole thing could be greatly simplified by using an inclusion tag.

Django cannot get dialog box to display relevant information

I have two forms that I am using on one (html page below) page. One form (create_task_form) create's tasks, and the other (edit_task_form) should edit/show tasks. To make things more difficult on myself I decided to display the tasks in a list, and when a user clicks on a task, it should display a form with the task details in a dialog box. Again, the create dialog box works as should, however I cannot figure out how to populate the (edit_task_form) edit/show form for a existing task from a list in a dialog box with the relevent task info.
Views.py: Edited
def status(request, project_id, task_id=None):
need_owner_list = Task.objects.filter(project__id=project_id, status=0)
in_progresss_list = Task.objects.filter(project__id=project_id, status=1)
pending_review_list = Task.objects.filter(project__id=project_id, status=2)
t = get_object_or_404(Task, pk=task_id)
p = get_object_or_404(Project, pk=project_id)
if project_id:
p = get_object_or_404(Project, pk=project_id)
else:
p = None
# if task_id:
# t = get_object_or_404(Task, pk=task_id)
# else:
# t = None
if request.method == 'POST':
p = get_object_or_404(Project, pk=project_id)
post_task = PostTaskForm(request.POST)
if post_task.is_valid():
task = post_task.save(commit=False)
task.project = p
task.save()
url = reverse('status', args=[project_id])
return HttpResponseRedirect(url)
else:
post_task = PostTaskForm()
if request.method == 'POST':
t = get_object_or_404(Task, pk=task_id)
tform = PostTaskForm(request.POST, instance = t)
if form.is_valid():
task = tform.save()
url = reverse('status', args=[project_id])
return HttpResponseRedirect(url)
else:
tform = PostTaskForm(instance=t)
c = Context({
'need_owner_list': need_owner_list,
'in_progresss_list': in_progresss_list,
'pending_review_list': pending_review_list,
'project': p,
'request': request,
'pform': post_task,
'task_id': task_id,
'project_id': project_id,
'task': t,
'tform': tform,
})
return render_to_response('project/status.html', c, context_instance=RequestContext(request))
HTML Page
{% extends "base.html" %}
{% block title %} project status {% endblock %}
{%block content %}
<body>
<head>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/status.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/create_task.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/status_box.css" />
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/list_items.css">
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/ownerless_task_list.css">
<!-- These are the scripts for the drag and drop functionality. -->
<script language="JavaScript" type="text/javascript" src="{{ STATIC_URL }}javascript/jquery.sortable.js"></script>
</head>
<div id=lists_box>
{% if need_owner_list %}
<ul id="needs_owner" class="connected list">
{% for task in need_owner_list|slice:":20" %}
<li class="row1"><a href="#divModalDialog1" >{{ task.title }} {% url task task.id%}</a></li>
{% endfor %}
</ul>
<div id="divModalDialog1" class="divModalDialog" type="hidden">
<div id=task_div>
X
<form id="edit_task_form" action="{{ task }}" value="{{ task }}" method="POST">
<input type="hidden" name="task" value="{{ task }}"/>
{% csrf_token %}
{{ pform }}
<input type="SubmitEdit" value="Submit Edit" onclick="self.close()">
<input type="Reset" value="Reset">
</form>
</div>
</div>
{% else %}
<ul id="needs_owner" class="connected list">
<li class="row1">No tasks are available.</li>
</ul>
{% endif %}
{% if in_progresss_list %}
<ul id="in_progress" class="connected list">
{% for task in in_progresss_list|slice:":20" %}
<li class="row1">{{ task.title }}</li>
{% endfor %}
</ul>
{% else %}
<ul id="in_progress" class="connected list">
<li class="row1">No tasks are available.</li>
</ul>
{% endif %}
{% if pending_review_list %}
<ul id="pending_status" class="connected list">
{% for task in pending_review_list|slice:":20" %}
<li class="row1">{{ task.title }}</li>
{% endfor %}
</ul>
{% else %}
<ul id="pending_status" class="connected list">
<li class="row1">No tasks are available.</li>
</ul>
{% endif %}
</div>
<!-- START:This section below is deals with the submit task popup window -->
{% if user.is_authenticated %}
<script>
$(function() {
$('.sortable').sortable();
$('.handles').sortable({
handle: 'span'
});
$('.connected').sortable({
connectWith: '.connected'
});
$('.exclude').sortable({
items: ':not(.disabled)'
});
});
</script>
<!-- The JS is added here to load after login. If this is added the the top of the page it conflicts with login_link.js -->
<script src="{{ STATIC_URL }}javascript/create_task.js" type="text/javascript"></script>
<a id="submit_task">submit task</a>
<div id="task_popout">
<a id="task_popoutClose">X</a>
{% if form.has_errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
<form id="create_task_form" action="" value="submit_task" method="POST">
<input type="hidden" name="project" value="{{ project_id }}"/>
{% csrf_token %}
{{ pform }}
<input type="Submit" value="Submit Task" onclick="self.close()">
<input type="Reset" value="Reset">
</form>
</div>
<div id="taskbackgroundPopup"></div>
{% else %}
<p id="login_message">Please <a style="color:blue;" href="#authenticate" id="task_chat">log in</a> to submit/edit tasks or particapate in chats.</p>
{% endif %}
<div id="ticket_stats">
<div id="owner_label" class="text">Owner:</div>
<div id="owner" class="text">{{project.owner|safe}}</div>
<div id="tags_label" class="text">Tags:</div>
<div id="tags" class="text">{{project.tags|safe}}</div>
<div id="created_label" class="text">Created:</div>
<div id="created_date" class="text">{{project.date_created|date:"d/m/Y"}}</div>
<div id="updated_label" class="text">Updated:</div>
<div id="last_updated" class="text">{{project.date_updated|date:"d/m/Y"}}</div>
</div>
</body>
{%endblock%}
models.py
class Project(models.Model):
title = models.CharField(max_length=50, verbose_name='')
slug = models.SlugField(max_length=50, editable=False)
owner = models.ForeignKey(User, editable=False)
problem = tinymce_models.HTMLField(verbose_name='')
date_created = models.DateTimeField(editable=False)
date_updated = models.DateTimeField(editable=False)
tags = TagField(verbose_name='')
def set_tags(self, tags):
Tag.objects.update_tags(self, tags)
def __unicode__(self):
return self.tags
def __unicode__(self):
return self.id
def __unicode__(self):
return self.title
#This overrides the save function in the project/views.py module. It checks the
#created date against the updated date, and updates the updated date if needed.
#Also this takes the title and slugifies it so it can be rendered in the URL.
def save(self, *args, **kwargs):
if not self.id:
self.date_created = datetime.now()
self.date_updated = datetime.now()
self.slug = slugify(self.title)
super(Project, self).save(*args, **kwargs)
class PostProjectForm(ModelForm):
class Meta:
model = Project
STATUS_CHOICES = (
('0', 'Needs Owner'),
('1', 'In Progress'),
('2', 'Comp/Pend/Review'),
('3', 'Complete')
)
class Task(models.Model):
title = models.CharField(max_length=50)
project = models.ForeignKey(Project, editable=False)
assignee = models.ForeignKey(User, null=True, blank=True)
task_desc = models.TextField()
solution = models.TextField(blank=True)
status = models.CharField(max_length=1, default='0', choices=STATUS_CHOICES)
date_created = models.DateTimeField(editable=False)
date_updated = models.DateTimeField(editable=False)
def save(self, *args, **kwargs):
if not self.id:
self.date_created = datetime.now()
self.date_updated = datetime.now()
super(Task, self).save(*args, **kwargs)
def __unicode__(self):
return self.id
def __unicode__(self):
return "%s" % self.object_pk
class PostTaskForm(ModelForm):
class Meta:
model = Task
URLs.py
url(r'^status/(?P<idea_id>\d+)$', 'status', name='status'),
url(r'^status/(?P<idea_id>\d+)/(?P<task_id>\d+)$', 'status', name='status_task'),
TL;DR
How can I get a the edit_task_form to display the relevant data from Tasks so that a user can edit/view a task?
Thanks in advance!
not sure but, you have...
if request.method == 'POST':
p = get_object_or_404(Project, pk=project_id)
post_task = PostTaskForm(request.POST)
...
else:
post_task = PostTaskForm()
^ so from the above it looks like it might not populate the form if you are making the dialog with a javascript GET request (?)