I am currently developping an application on django and when i send a post request from a form, is_valid method return false, but form.is_bound return True.
my form.error -> mailThis field is required.prenomThis field is required.nomThis field is required.
my forms.py
from django import forms
class formadduser(forms.Form):
mail = forms.CharField(label='Mail', max_length=40)
# imput_username = forms.CharField(input='input_username', max_length=100)
prenom = forms.CharField(label='Prénom', max_length=25)
# input_password = forms.CharField(input='input_pathword', max_length=100)
nom = forms.CharField(label = 'Nom', max_length=25)
views.py where i'm trying to get the form inputs:
from re import S
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect, QueryDict
from .forms import formadduser
import pickle
import os
from .fonctions import tri
from .models import Users
# Create your views here.
def administrator(request) :
# test = request.POST[username]
# print(test)
# request.form['username'] je crois que c'est du flask
return render(request, 'admin.html')
def index(request):
if request.method == 'POST':
var = request.POST["username"]
print(var)
text = """<h1>{{var}}</h1>
<p>les crepes nananinanana</p>"""
return HttpResponse(text)
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = formadduser(request.POST)
print(form)
# check whether it's valid:
if form.is_valid():
print("debug")
print(form.cleaned_data["mail"])
var = Users(mail = form.cleaned_data["Mail"], prenom = form.cleaned_data["Prenom"], nom = form.cleaned_data["Nom"])
var.save()
# process the data in form.cleaned_data as required
# ...
# print(NameForm.username)
# redirect to a new URL:
# return HttpResponseRedirect('/thanks/')
# Username = form.cleaned_data
# text = """<h1>{{form.cleaned_data["username"]}}</h1>
# <p>les crepes nananinanana</p>"""
# return HttpResponse(text)
# print(form.cleaned_data["username"])
# u = USERS(Username = form.cleaned_data["username"], droits = form.cleaned_data["droits"])
# u.save()
# query = pickle.loads("zeubi")
# test = list(USERS.objects.values("Username"))
# test = USERS.objects.values("Username")
# test = USERS.objects.all()
# test = str(USERS.objects.values("droits"))
# res = tri(test)
# user_qs = USERS.objects.all()
# for user in user_qs:
# print(user['Username'])
# testv = QueryDict
# test.query = query
return render(request, 'admin.html')
# return render(request, 'admin.html', {'test' : test})
# return(locals())
# USERS.Username = form.cleaned_data["username"]
# return form.cleaned_data
else:
print("invalid form")
print(form.is_bound)
# print(form.errors)
# if a GET (or any other method) we'll create a blank form
else:
print("error")
form = formadduser()
return render(request, 'admin.html', {'form': form})
templates.py with 4 forms but my test is on formadduser:
<!DOCTYPE html>
<html lang="fr">
<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>ADMIN</title>
{% load static %}
<script src="{% static 'global/jquery.js' %}"></script>
<script src="{% static 'administrator/admin.js' %}"></script>
<link rel="stylesheet" type="text/css" href="{% static 'administrator/admin.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'global/StyleGlobal.css' %}">
</head>
<body id="idbody" onclick="fout();foutform()">
<div class="bande">
<div onclick="testhb()" id="hb">
<div class="barre"></div>
<div class="barre"></div>
<div class="barre"></div>
<ul id="ulmenu">
<li class="menu"><a class="textdeco" href="http://10.75.101.201/Front/mat/mat.html">Materiel</a></li>
<li class="menu"><a class="textdeco" href="http://10.75.101.201/Front/offrecgr/offrecgr.html">Offres/CGR</a></li>
</ul>
</div>
<!-- </div> -->
<div class="logo">
<img src="{% static 'global/GHD.png' %}" alt="Logo">
<!-- -->
</div>
</div>
<div class="titre">
<h1 class="accueiltxt">ADMIN</h1>
</div>
<div class="gigacontainer" id="gigacontainer">
<div class="containerbutton">
<div class="button" id="buttonsuppuser" onclick = "buttonsuppuser()">
<p class="trashcan">🗑</p></div>
<div class="button" id="buttonadduser" onclick="buttonadduser()">+</div>
<div class="txtbutton">Users</div>
<div class="button" id="buttonsuppapp" onclick = "buttonsuppapp()">🗑</div>
<div class="button" id="buttonaddapp" onclick = "buttonaddapp()">+ </div>
<div class="txtbutton">Apps</div>
</div>
<form action="" method="post" class="form" id="formsuppuser">
{% csrf_token %}
<label for="suppuser">Username</label>
<input type="text" name="suppuser" id="suppuser">
<button>Supprimer</button>
</form>
<form name="formadduser" action="" method="post" class="form" id="formadduser">
{% csrf_token %}
<label for="addusermail">Mail</label>
<input required="required" type="text" name="addusermail" id="addusermail">
<label for="adduserprenom">Prénom</label>
<input required="required" type="text" name="adduserprenom" id="adduserprenom">
<label for="addusernom">Nom</label>
<input required="required" type="text" name="addusernom" id="addusernom">
<button type="submit">Ajouter</button>
</form>
<form action="" method="post" class="form" id="formsuppapp">
{% csrf_token %}
<label for="suppapp">Application</label>
<input type="text" name="suppapp" id="suppapp">
<button>Supprimer</button>
</form>
<form action="" method="post" class="form" id="formaddapp">
{% csrf_token %}
<label for="addapp">Application</label>
<input type="text" name="addapp" id="addapp">
<button>Ajouter</button>
</form>
</div>
</html>
You should have the errors in form.errors, without them, we cannot tell you anything.
It may also be that your form is not bound (request data have not be sent to the form). You can check this with form.is_bound.
If this return false, you did not send your data into your form:
form = MyForm(data=request.POST)
You can see how is_valid works in the django source.
As you can see, you can know whats wrong juste by checking form.is_bound or form.errors.
Related
`#views.route('/flight.html',methods = ['GET','POST'])
def flight():
if request.method == 'POST':
global no_of_passenger
no_of_passengers = request.form.get('no_of_passengers')`
In the above view, I'm getting the passenger count from an earlier html page which I'm using later. I need to get the input from the user as many times as the no_of_passengers.
`#views.route('/passengers.html',methods = ['GET','POST'])
def passenger():
if request.method == 'POST':
return render_template('passengers.html')
return render_template('passengers.html')
#views.route('/passengersinfo.html',methods = ['GET','POST'])
def passenger_information():
passengercount = no_of_passengers
passengercount = int(passengercount)
print(passengercount)
if request.method == 'POST':
for i in range(0,passengercount):
passenger_info = {}
passenger_info['passengername'] = request.form.get('Passenger_Name')
passenger_info['Street'] = request.form.get('Street')
passenger_info['City'] = request.form.get('City')
passenger_info['State'] = request.form.get('State')
passenger_info['ZipCode'] = request.form.get('ZipCode')
return redirect(url_for("views.passenger"))
return render_template('passengersinfo.html')`
In this view I'm trying to run the form as per the user input using a for loop.
The below attached code is the HTML form which is used to get the user form data.
`{% extends 'base.html'%}
{% block title %}Passenger Information Page{% endblock %}
{% block content %}
<form id="Form1" action = 'passengersinfo.html' method = 'POST'>
<div>
<label for ='Passenger_Name' >Passenger Name</label>
<input type = 'text' name = 'Passenger_Name' id='Passenger_Name' id="Form1">
<br>
<label for ='Street' >Street</label>
<input type = 'text' name = 'Street' id='Street' id="Form1">
<br>
<label for ='City' >City</label>
<input type = 'text' name = 'City' id='City' id="Form1">
<br>
<label for ='State' >State</label>
<input type = 'text' name = 'State' id='State' id="Form1">
<br>
<label for ='Zip' >Zip Code</label>
<input type = 'text' name = 'Zip' id='Zip' id="Form1">
</div>
<button type = 'submit' id="Form1" >Next</button>
</form>
{%endblock%}
`
An easy way to implement your requirements is to use Flask-WTF.
Using a FieldList and a FormField, it is possible to create a list of a predefined form.
In this way you create a form for your address details and, depending on the required number, you duplicate this. In addition, you can validate the entries made.
If you only want to display one nested form at a time, you can use JavaScript to navigate forward or back.
The following example uses the session to avoid using global variables and stay as close to your defaults as possible.
Flask
from flask import (
Flask,
redirect,
render_template,
request,
session,
url_for
)
from flask_wtf import FlaskForm, Form
from wtforms import (
FieldList,
FormField,
IntegerField,
StringField,
SubmitField
)
from wtforms.validators import (
InputRequired,
NumberRange
)
app = Flask(__name__)
app.secret_key = 'your secret here'
class PassengersForm(FlaskForm):
passenger_count = IntegerField('Ticket Count',
validators=[NumberRange(min=1)]
)
submit = SubmitField('Next')
class PassengerForm(Form):
name = StringField('Name',
validators=[InputRequired()]
)
street = StringField('Street/No')
city = StringField('City')
state = StringField('State')
zipcode = StringField('Zip')
class PassengerDetailsForm(FlaskForm):
passengers = FieldList(FormField(PassengerForm))
submit = SubmitField()
#app.route('/passengers', methods=['GET', 'POST'])
def passengers():
form = PassengersForm(request.form, data={'passenger_count': 1})
if form.validate_on_submit():
session['count'] = form.passenger_count.data
return redirect(url_for('.passengers_info'))
return render_template('passengers.html', **locals())
#app.route('/passengers-info', methods=['GET', 'POST'])
def passengers_info():
form = PassengerDetailsForm(request.form)
form.passengers.min_entries = max(1, int(session.get('count', 1)))
while len(form.passengers.entries) < form.passengers.min_entries:
form.passengers.append_entry()
if form.validate_on_submit():
for passenger in form.passengers.data:
print(passenger)
return redirect(url_for('.passengers'))
return render_template('passengers_info.html', **locals())
HTML (./templates/passengers.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Passengers</title>
</head>
<body>
<form method="post">
{{ form.csrf_token }}
<div>
{{ form.passenger_count.label() }}
{{ form.passenger_count() }}
{% if form.passenger_count.errors -%}
<ul>
{% for error in form.passenger_count.errors -%}
<li>{{ error }}</li>
{% endfor -%}
</ul>
{% endif -%}
</div>
{{ form.submit }}
</form>
</body>
</html>
HTML (./templates/passengers_info.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Passenger Informations</title>
<style type="text/css">
.step {
display: none;
}
.step.active {
display: block;
}
</style>
</head>
<body>
<form method="post">
{{ form.csrf_token }}
{% for subform in form.passengers -%}
<div class="step {%if loop.first %}active{% endif %}" id="step-{{loop.index0}}">
{% for field in subform -%}
<div>
{{ field.label() }}
{{ field() }}
{% if field.errors -%}
<ul>
{% for error in field.errors -%}
<li>{{ error }}</li>
{% endfor -%}
</ul>
{% endif -%}
</div>
{% endfor -%}
{%if not loop.first %}
<button type="button" class="btn-prev">Prev</button>
{% endif %}
{%if not loop.last %}
<button type="button" class="btn-next">Next</button>
{% else %}
{{ form.submit() }}
{% endif %}
</div>
{% endfor -%}
</form>
<script type="text/javascript">
(function() {
let step = 0;
const btns_next = document.querySelectorAll('.btn-next');
btns_next.forEach(btn => {
btn.addEventListener('click', evt => {
[`step-${step}`, `step-${++step}`].forEach(sel => {
const elem = document.getElementById(sel);
elem && elem.classList.toggle('active');
});
});
});
const btns_prev = document.querySelectorAll('.btn-prev');
btns_prev.forEach(btn => {
btn.addEventListener('click', function(evt) {
[`step-${step}`, `step-${--step}`].forEach(sel => {
const elem = document.getElementById(sel);
elem && elem.classList.toggle('active');
});
});
});
})();
</script>
</body>
</html>
I try to upload two forms with one submit button.
A user can select a pdf file and a excel file. And then uploading both files. And then the contents of both are returned.
So I try to upload both files with one submit button.
But the two selected file options are not visible for uploading the files.
So I have the template like this:
{% extends 'base.html' %} {% load static %} {% block content %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Create a Profile</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="{% static 'main/css/custom-style.css' %}" />
<link rel="stylesheet" type="text/css" href="{% static 'main/css/bootstrap.css' %}" />
</head>
<body>
<div class="container center">
<span class="form-inline" role="form">
<div class="inline-div">
<form class="form-inline" action="/controlepunt140" method="POST" enctype="multipart/form-data">
<div class="d-grid gap-3">
<div class="form-group">
{% csrf_token %}
{{ form.0.as_p }}
<button type="submit" name="form_pdf" class="btn btn-warning">Upload!</button>
</div>
<div class="form-outline">
<div class="form-group">
<textarea class="inline-txtarea form-control" id="content" cols="70" rows="25">
{{content}}</textarea>
</div>
</div>
</div>
<div class="d-grid gap-3">
<div class="form-group">
{{ form.1.as_p }}
</div>
<div class="form-outline">
<div class="form-group">
<textarea class="inline-txtarea form-control" id="content" cols="70" rows="25">
{{conten_excel}}</textarea>
</div>
</div>
</div>
</form>
</div>
</span>
</div>
</body>
</html>
{% endblock content %}
and the views.py:
class ReadingFile(View):
def get(self, *args, **kwargs):
return render(self.request, "main/controle_punt140.html", {
"form1": UploadFileForm(),
"form2": ExcelForm()
})
def post(self, *args, **kwargs):
filter_text = FilterText()
types_of_encoding = ["utf8", "cp1252"]
form1 = UploadFileForm(
self.request.POST, self.request.FILES, prefix="form1")
form2 = ExcelForm(self.request.FILES,
self.request.FILES, prefix="form2")
content = ''
content_excel = ''
if form1.is_valid() and form2.is_valid() and self.request.POST:
uploadfile = UploadFile(image=self.request.FILES["upload_file"])
excel_file = self.request.FILES["upload_file"]
uploadfile.save()
for encoding_type in types_of_encoding:
with open(os.path.join(settings.MEDIA_ROOT, f"{uploadfile.image}"), 'r', encoding=encoding_type) as f:
if uploadfile.image.path.endswith('.pdf'):
content = filter_text.show_extracted_data_from_file(
uploadfile.image.path)
else:
content = f.read()
if uploadfile.image.path.endswith('xlsx'):
wb = openpyxl.load_workbook(excel_file)
worksheet = wb['Sheet1']
print(worksheet)
excel_data = list()
for row in worksheet.iter_rows():
row_data = list()
for cell in row:
row_data.append(str(cell.value))
excel_data.append(row_data)
print(excel_data)
content_excel = excel_data
else:
content_excel = f.read()
return render(self.request, "main/controle_punt140.html", {
'form1': ExcelForm(),
'form2': UploadFileForm(),
"content": [content, content_excel]
})
# I've adjusted the indent here to what I think it should be.
return render(self.request, "main/controle_punt140.html", {
"form1": form1,
"form2": form2,
})
and forms.py:
class UploadFileForm(forms.Form):
upload_file = forms.FileField(required=False)
class ExcelForm(forms.Form):
upload_file = forms.FileField(required=False)
urls.py:
urlpatterns = [
path('', views.starting_page, name='starting_page'),
path('controlepunt140', views.ReadingFile.as_view(), name='controlepunt140'),
]
The variable name used in the template is the key of the dictionary, not the value. The value is what is inserted into the template when django renders the page.
You have {{form1.as__p}} in your template, but you send "form": [form1, form2] as your context, so the variable in the template should be {{ form.0.as_p }} and {{ form.1.as_p }}. I haven't tested this, but if it doesn't work, you could just send the two forms separately like:
from django.shortcuts import redirect
class ReadingFile(View):
def get(self, *args, **kwargs):
return render(self.request, "main/controle_punt140.html", {
"form1": UploadFileForm(),
"form2": ExcelForm()
})
def post(self, *args, **kwargs):
filter_text = FilterText()
types_of_encoding = ["utf8", "cp1252"]
form1 = UploadFileForm(self.request.POST, self.request.FILES, prefix="form1")
form2 = ExcelForm(self.request.FILES, self.request.FILES, prefix="form2")
content = ''
content_excel = ''
if form1.is_valid() and form2.is_valid() and self.request.POST:
uploadfile = UploadFile(image=self.request.FILES["upload_file"])
excel_file = self.request.FILES["upload_file"]
uploadfile.save()
for encoding_type in types_of_encoding:
with open(os.path.join(settings.MEDIA_ROOT, f"{uploadfile.image}"), 'r', encoding=encoding_type) as f:
if uploadfile.image.path.endswith('.pdf'):
content = filter_text.show_extracted_data_from_file(
uploadfile.image.path)
else:
content = f.read()
if uploadfile.image.path.endswith('xlsx'):
#Uploading excel form:
#this is just logic.
pass
else:
content_excel = f.read()
# You probably should do a redirect after the form is
# submitted, rather than render the page.
return redirect('main:controlepunt140')
# return render(self.request, "main/controle_punt140.html", {
'form1': ExcelForm(),
'form2': UploadFileForm(),
"content": [content, content_excel]
})
# I've adjusted the indent here to what I think it should be.
return render(self.request, "main/controle_punt140.html", {
"form1": form1,
"form2": form2,
})
You probable should also change to a redirect after the form is submitted and saved successfully. Check out Post/Redirect/Get and/or rendering content after a succesful post request.
Edit
Changed template to use {{ form.0.as_p }} as indicated by #nigel239
You can redirect to the same page where the form was submitted, so if the user hits the refresh button on their browser for some reason, you will not get an alert box asking the user to resend the form.
I am trying to set up two different forms on the same Flask page with validators, but it keeps telling me my forms are not defined. I get error:
The code is designed to allow users to input a number and check if it is abundant, perfect, or deficient, and then with a separate form to allow users to define a range and get how many abundant, perfect or deficient numbers there are within that range.
My code is as follows:
from flask import Flask, render_template, request
from flask_wtf import Form
from wtforms import IntegerField
from wtforms.validators import InputRequired
from perfect_numbers import classify, listInRange
app = Flask(__name__)
app.config['SECRET_KEY'] = 'DontTellAnyone'
class PerfectForm(Form):
inputNumber = IntegerField('input a number', default=1, validators=[InputRequired(message='Please input an integer')])
class PerfectRangeForm(Form):
startNumber = IntegerField('input a number', default=1, validators=[InputRequired(message='Please input an integer')])
endNumber = IntegerField('input a number', default=1, validators=[InputRequired(message='Please input an integer')])
#app.route('/', methods=['GET', 'POST'])
def index():
form1 = PerfectForm(request.form, prefix="form1")
num = 1
Classify = classify(num)
if form.validate_on_submit() and form.data:
num = request.form1['inputNumber']
Classify = classify(form1.inputNumber.data)
return render_template('index.html', form1=form1, num=num, classify=Classify)
return render_template('index.html', num=1, form1=form1, classify=Classify)
#app.route('/aliRange', methods=['GET', 'POST'])
def aliRange():
form2 = PerfectRangeForm(request.form2, prefix="form2")
startNumber = 1
endNumber = 1
aliquot = 'abundant'
Classify = classify(num)
ListInRange = listInRange(startNumber, endNumber, aliquot)
if form2.validate_on_submit() and form2.data:
startNumber = request.form2['startNumber']
endNumber = request.form2['endNumber']
aliquot = request.form2['aliquot']
ListInRange = listInRange(startNumber, endNumber, aliquot)
return render_template('index.html', form2=form2, startNumber=startNumber, endNumber=endNumber, ListInRange=listInRange)
return render_template('index.html', form2=form2, startNumber=startNumber, endNumber=endNumber, ListInRange=listInRange)
if __name__ == '__main__':
app.run(debug=True)
index.html:
{% from "_formhelpers.html" import render_field %}
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>WTForms</title>
</head>
<body>
<div>
<form action="/" method="POST">
<dl>
{% if form1 %}
{{ form1.csrf_token }}
{{ render_field(form1.inputNumber) }}
{% endif %}
<input type="submit" value="submit1">
</dl>
</form>
</div>
<div>
{{ num }} is {{ classify }}
</div>
<div></div>
<div>
<form action="/aliRange" method="POST">
<div class="form-group">
<p>Input a start number and an end number to return a list of...</p>
<select class="form-control" action="/aliRange" name="aliquot" method="POST">
<option value = 'abundant'>Abundant</option>
<option value = 'perfect'>Perfect</option>
<option value = 'deficient'>Deficient</option>
</select>
<p>...numbers within that range</p>
<form action="/aliRange" method="POST">
<dl>
{% if form2 %}
{{ form2.csrf_token }}
{{ render_field(form2.startNumber) }}
{{ render_field(form2.endNumber) }}
{% endif %}
<input class="btn btn-primary" type="submit" value="submit">
</dl>
</form>
</div>
</form>
The {{ aliquot }} numbers between {{ startNumber }} and {{ endNumber }} are:
{{ listInRange }}
</div>
</body>
</html>
Error I get atm is: AttributeError: 'Request' object has no attribute 'form1'
EDIT:
You can simplify your code using a single view, using the submit value to differentiate the handling of the first form and the second one.
The modified code is:
class PerfectForm(Form):
inputNumber = IntegerField('input a number', default=1, validators=[InputRequired(message='Please input an integer')])
class PerfectRangeForm(Form):
startNumber = IntegerField('input a number', default=1, validators=[InputRequired(message='Please input an integer')])
endNumber = IntegerField('input a number', default=1, validators=[InputRequired(message='Please input an integer')])
aliquot = StringField('input a kind', default='perfect')
#app.route('/', methods=['GET', 'POST'])
def index():
form1 = PerfectForm(request.form, prefix="form1")
form2 = PerfectRangeForm(request.form, prefix="form2")
num = 1
Classify = classify(num)
startNumber = 1
endNumber = 1
aliquot = 'abundant'
ListInRange = listInRange(startNumber, endNumber, aliquot)
if request.form.get('submit') == 'submit-1':
if form1.validate_on_submit() and form1.data:
num = form1.data['inputNumber']
Classify = classify(num)
elif request.form.get('submit') == 'submit-2':
if form2.validate_on_submit() and form2.data:
startNumber = form2.data['startNumber']
endNumber = form2.data['endNumber']
aliquot = form2.data['aliquot']
ListInRange = listInRange(startNumber, endNumber, aliquot)
return render_template('index.html',
num=num, classify=Classify,
startNumber=startNumber, endNumber=endNumber, aliquot=aliquot, ListInRange=ListInRange,
form1=form1, form2=form2)
if __name__ == '__main__':
app.run(debug=True)
and the modified template index.html is:
{% from "_formhelpers.html" import render_field %}
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>WTForms</title>
</head>
<body>
<div>
<form action="/" method="POST">
<dl>
{{ form1.csrf_token }}
{{ render_field(form1.inputNumber) }}
<input type="submit" name="submit" value="submit-1">
</dl>
</form>
</div>
{% if num %}
<div>
{{ num }} is {{ classify }}
</div>
{% endif %}
<hr />
<div>
<form action="/" method="POST">
{{ form2.csrf_token }}
<div class="form-group">
<p>Input a start number and an end number to return a list of...</p>
<select class="form-control" action="/aliRange" name="aliquot" method="POST">
<option value = 'abundant'>Abundant</option>
<option value = 'perfect'>Perfect</option>
<option value = 'deficient'>Deficient</option>
</select>
<p>...numbers within that range</p>
<dl>
{{ render_field(form2.startNumber) }}
{{ render_field(form2.endNumber) }}
</dl>
<input class="btn btn-primary" type="submit" name="submit" value="submit-2">
</div>
</form>
<div>
The {{ aliquot }} numbers between {{ startNumber }} and {{ endNumber }} are:
{{ listInRange }}
</div>
</div>
</body>
</html>
OLD:
You are using form1 in the template but passing form inside the template context:
render_template('index.html', form=form1, num=num, classify=Classify)
You can either change form1 to form inside the template, or pass form1=form1 in the above line.
If you are rendering multiple forms inside the same template, you have to pass all the respective form variables: form1, form2, ... from all the views rendering that template. Otherwise the template rendering will raise the error you are seeing.
If you are interested in having a single form rendered among all the possible ones inside the template, you can use conditional rendering using
{% if form1 %}
<div>
<form action="/" method="POST">
<dl>
{{ form1.csrf_token }}
...
</dl>
</form>
</div>
{% endif %}
{% if form2 %}
<form action="/aliRange" method="POST">
...
</form>
{% endif %}
...
Also, your html seems incorrect to me, because you have a form nested inside another form. Not sure about what you are trying to obtain there.
I am working on a blog project and I am getting the "Matching query does not exist "error. I have tried using try block thinking that the model class might not be returning any value. Hence, modified my views.py as below:-
from django.shortcuts import render, HttpResponseRedirect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password
from django.db.models import Q
from .forms import *
# Create your views here.
def home(request):
print("I am home")
try:
blog_data = BlogPost.objects.all()
print("blog_data", blog_data)
except BlogPost.DoesNotExist:
blog_data = None
print("blog_data", blog_data)
try:
last_element = BlogPost.objects.filter(id = len(blog_data))[0]
print("last_element", last_element)
except BlogPost.DoesNotExist:
last_element = None
print("last_element", last_element)
tags_list = BlogPost.objects.values_list("tags", flat = True).distinct()
#tags_list = BlogPost.objects.all().distinct()
context = {'blog_data':blog_data, "last_element":last_element, "tags_list":tags_list}
#last_element = list(BlogPost.objects.all().reverse()[0])
print("last_element",last_element, "blog_data",blog_data,"context",context)
return render(request, 'blog/home.html', context)
# def home(request):
# blog_data = BlogPost.objects.all()
# context = {'blog_data':blog_data}
# print('context', context)
# last_element = BlogPost.objects.all().reverse()[0]
# #last_element = BlogPost.objects.all().reverse()[0]
# return render(request, 'blog/home.html', context)
def new_post(request):
if request.method == 'POST':
form = BlogForm(data = request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('home')
else:
form = BlogForm()
return render(request, 'blog/blogform.html', {'form':form })
def login_user(request):
username = password = ''
state = "Please log in"
if request.POST:
username = request.POST.get('Username')
password = request.POST.get('Password')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
state = "You're successfully logged in!"
return HttpResponseRedirect('/blog/home')
else:
state = "Your account is not active, please contact the site admin."
else:
state = "Your username and/or password were incorrect."
#return render_to_response('main/login.html',{'state':state, 'username': username})
return render(request, "blog/login.html", {'state':state, 'username': username, 'next_page':"home.html"})
#return HttpResponseRedirect("home.html")
def logout_user(request):
logout(request)
return render(request,'blog/home.html')
def register_user(request):
username = password = password_again = email = ''
state = ''
if request.method == 'POST':
username = request.POST.get('Username')
password = request.POST.get('Password')
password_again = request.POST.get('Password_again')
email = request.POST.get('Email')
print('email', email)
if password == password_again:
password = make_password(password, salt = None, hasher = 'default')
else:
state = "Password and password re-entered do not match, please try again..."
return HttpResponseRedirect('login')
print("at 63")
try:
user = User.objects.get(username = username)
print('user at 67', user)
except Exception as e:
print("Error is :", e)
user = None
print("user", user)
try:
emailID = User.objects.get(email = email)
print("emailID", emailID)
except Exception as e:
print("Error is :", e)
emailID = None
print("emailID exception", emailID)
if user is not None:
state = 'Username already exists, please try another one...'
else:
if emailID is None:
new_user = User(username = username, password = password, email = email)
##Adding new logic for securityQAs vvv
#new_SQA = SecurityQA(user_email = email, security_question = security_question, security_answer = security_answer)
##Adding new logic for securityQAs ^^^
new_user.save()
#new_SQA.save()
state = 'You are successfully registered.. Thanks'
return HttpResponseRedirect('login')
else:
state = "Email ID already registered, try a new one.."
print('state at else', state)
#return HttpResponseRedirect('login')
return render(request, "blog/register.html", {'state':state, 'username':username, 'next_page':'home.html'})
def forgot_password(request):
pass
def comment_posted(request):
return render(request, "blog/comment_posted.html")
def blog_search(request):
qset = Q()
keyword = ''
keyword = request.POST.get('keyword')
print("keyword", keyword)
for word in keyword.split():
qset |= (Q(title__contains = word)|Q(description__contains = word))
print('qset', qset)
result = BlogPost.objects.filter(qset)
context = {'result':result}
return render(request, 'blog/blog_search.html', context)
Also, find my models.py below
from django.db import models
from django.contrib.auth.models import User
#from django.core.files.storage import FileSystemStorage
#fs = FileSystemStorage(location='E:\django\myblog\\blog\uploaded images')
# Create your models here.
class BlogPost(models.Model):
title = models.CharField(max_length = 30)
posted_by = models.CharField(max_length = 30)
posted_on = models.DateTimeField(auto_now_add = True)
description = models.CharField(max_length = 200)
comment = models.CharField(max_length = 150)
tags = models.CharField(max_length=50, default = "notag")
image = models.ImageField(upload_to = 'uploaded_images', default = None, null = True, blank = True)
def __str__(self):
#return "{0} : {1}".format(self.title, self.description)
return self.title
template code as below (home.html). Here I am getting the error at line "{% get_comment_list for blog.blogpost last_element.id as comment_list %}"
{% load staticfiles %}
{%load comments%}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Sourav's blog</title>
<!-- Bootstrap Core CSS -->
{%block styling%}
<link href="{%static 'css/bootstrap.min.css'%}" rel="stylesheet">
<!-- Custom CSS -->
<link href="{%static 'css/blog-post.css'%}" rel="stylesheet">
{%endblock styling%}
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Ideate</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li>
New idea
</li>
<!-- <li>Login</li> -->
{{user.is_authenticated}}
{% if user.is_authenticated %}
<li>
Logout
</li>
{% else %}
<li>
Login
</li>
{% endif %}
<li>
Help
</li>
{% if user.is_authenticated %}
<li>
Hi {{user.username}}
</li>
{%else%}
{% endif %}
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container -->
</nav>
<!-- Page Content -->
<div class="container">
<div class="row">
<!-- Blog Post Content Column -->
<div class="col-lg-8">
<!-- Blog Post -->
<!-- Title -->
<h1>Idea Blog</h1>
<!-- Author -->
<p class="lead">
by Sourav
</p>
<hr>
<!-- Date/Time -->
<p><span class="glyphicon glyphicon-time"></span>
Posted on
<!-- {%for i in blog_data%}
{{i.posted_on}}
{%endfor%}</p> -->
{{last_element.posted_on}}
<hr>
<!-- Preview Image -->
<img class="img-responsive" src="http://placehold.it/900x300" alt="">
<hr>
<!-- Post Content -->
<!-- <p>Below is the result</p> -->
<!-- <p>{{blog_data}}</p> -->
<p>
<!-- {%for i in blog_data%}
<h1>{{i.title}}</h1>
<p>{{i.description}}</p>
{%empty%}
<span>No data</span>
{%endfor%} -->
<!-- {{last_element}} -->
<h1>{{last_element.title}}</h1><span> posted by {{last_element.posted_by}}</span>
<p>Description : {{last_element.description}}</p>
{{last_element.image}}
<p>Tags : {{last_element.tags}}</p>
{% get_comment_count for blog.blogpost last_element.id as comment_count %}
<p>{{ comment_count }} comments have been posted.</p>
{% get_comment_list for blog.blogpost 1 as comment_list %}
{% for comment in comment_list %}
<p>Posted by: {{ comment.user_name }} on {{ comment.submit_date }}</p>
<p>Comment: {{ comment.comment }}</p>
{% endfor %}
{% get_comment_form for blog.blogpost last_element.id as form %}
<!-- A context variable called form is created with the necessary hidden
fields, timestamps and security hashes -->
<table>
<form action="{% comment_form_target %}" method="post">
{% csrf_token %}
{{ form }}
<tr>
<td colspan="1">
<input type="submit" name="submit" value="Post">
<input type="submit" name="preview" value="Preview">
<input type="hidden" name="next" value="{% url 'comment_posted' %}" />
</td>
</tr>
</form>
</table>
{% get_comment_list for blog.blogpost last_element.id as comment_list %}
{%for comment in comment_list%}
<li><b>{{comment.name}}</b> has posted comment on {{comment.submit_date}} </li>
<ul><li>{{comment.comment}}</li></ul>
<a name="c{{ comment.id }}"></a>
<a href="{% get_comment_permalink comment %}">
see comment details
</a>
{%endfor%}
</p>
</div>
<div class="col-md-4">
<!-- Blog Search Well -->
<form action = "{%url 'blog_search'%}" method = "POST">
<div class="well">
<h4>Blog Search</h4>
<div class="input-group">
{%csrf_token%}
<input type="text" class="form-control" name = "keyword", placeholder = "Enter search keyword">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
<span class="glyphicon glyphicon-search"></span>
</button>
</span>
</div>
<!-- /.input-group -->
</div>
</form>
<!-- Blog Categories Well -->
<div class="well">
<h4>Tags</h4>
<div class="row">
<div class="col-lg-6">
<ul class="list-unstyled">
<!-- {%for a in tags_list%}
{{a}}
{%endfor%} -->
<!-- {%for a in tags_list%}
{{a}}
{%endfor%} -->
{%for a in tags_list%}
{{a}},
{%endfor%}
<!-- <li>Category Name
</li>
<li>Category Name
</li>
<li>Category Name
</li>
<li>Category Name
</li> -->
</ul>
</div>
<div class="col-lg-6">
<ul class="list-unstyled">
<li>Category Name
</li>
<li>Category Name
</li>
<li>Category Name
</li>
<li>Category Name
</li>
</ul>
</div>
</div>
<!-- /.row -->
</div>
<!-- Side Widget Well -->
<div class="well">
<h4>Side Widget Well</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore, perspiciatis adipisci accusamus laudantium odit aliquam repellat tempore quos aspernatur vero.</p>
</div>
</div>
</div>
</div>
</div>
<!-- Blog Sidebar Widgets Column -->
<!-- /.row -->
<hr>
<!-- Footer -->
<footer>
<div class="row">
<div class="col-lg-12">
<p>Copyright © Your Website 2014</p>
</div>
</div>
<!-- /.row -->
</footer>
</div>
<!-- /.container -->
<!-- jQuery -->
{%block javascript%}
<script src="{%static 'js/jquery.js'%}"></script>
<!-- Bootstrap Core JavaScript -->
<script src="{%static 'js/bootstrap.min.js'%}"></script>
{%endblock javascript%}
</body>
</html>
When I am loading my homepage (home.html) I am not facing any issue, however, when I am trying to logout after logging in i am facing the error . My logout view is rendering home.html also. However, in this case it doesn't work. Please help me out of this. I am stuck.
My quick answer is that the logout view function is not providing the context variables that the home.html template needs. Try redirecting to the home view instead.
I'm making a sign in system in Django Python, i've been preparing the forms.py, views.py and the template itself, but so far the form fail to load on the template, can anyone help?
Forms.py
class Email_Only_SignUp_Form(forms.Form):
email = forms.EmailField(initial='Your Email...')
Views.py
def email_only_signup_form(request, template_name):
if request.method == 'POST':
signup_form = Email_Only_SignUp_Form(request.POST)
if signup_form.is_valid():
email = signup_form.cleaned_data['email']
username = email
try:
#check for duplicate username
User.objects.get(username=username)
email_error = 'email already exist'
except:
#initial creation of user object
try:
import os, random, string
length = 13
chars = string.ascii_letters + string.digits + '!#$()'
random.seed = (os.urandom(1024))
password = ''.join(random.choice(chars) for i in range(length))
User.objects.create_user(username,
username,
password,
)
user = User.objects.get(username=username)
user_profile=UserProfile(user=user)
user_profile.save()
#send email to user
try:
admin_email = settings.EMAIL_ORIGIN_MEMBERS
email_txt = loader.get_template('account/emails/createaccount.html')
email_html = loader.get_template('account/emails/createaccounthtml.html')
email_context = Context({'u_name': username,
'username': username,
'password': password,
})
new_user_mail = EmailMultiAlternatives('Welcome!',
email_txt.render(email_context),
admin_email,
[user.email, ],
headers={'Reply-To': 'admin#admin.com'}
)
new_user_mail.attach_alternative(email_html.render(email_context), 'text/html')
new_user_mail.send()
except:
pass
return redirect('/account/thankyou/?next=%s'%next)
except:
pass
else:
print('user form in not valid')
else:
signup_form = Email_Only_SignUp_Form()
return render_to_response(template_name, locals(), context_instance=RequestContext(request))
email_only_signup_form.html
{% extends "index.html" %}
{% block heroslider %}
<div class="page_title2" style="padding:150px 0px 50px 0px;">
<div class="container">
<h1>User Registration</h1>
</div>
</div><!-- end page title -->
{% endblock %}
{% block main_body %}
<style type="text/css">
input[type='radio'], input[type='checkbox'] {
width:20px;
vertical-align: middle;
}
div.reg_error {
position:relative;
top:-10px;
margin-top:0px;
padding-top:0px;
color:red;
}
</style>
<div class="container">
<form class="pagesignup logiform" action="" method="POST">{% csrf_token %}
<div class="row">
<div class="large-12 columns" style="margin-bottom: 30px;">
<div class="reg_form">
<div class="sky-form">
<header>REGISTER</header>
</div>
<div class="row">
<div class="large-12 columns">
<p>Email<br/>
{{signup_form.email}}
<div class="reg_error">{{ signup_form.email.errors.as_text }}{{email_error}}</div></p>
</div>
</div>
<div class="row">
<div class="large-12 large-centered columns" style="text-align:center;padding:20px;">
<input class="but_medium1" style="border:none;" type = "submit" value="REGISTER" /><br>
<br>By clicking on register, you have read and agreed to our terms of use
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<!-- Google Code for Sign Up Page (landed) Conversion Page -->
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = 969557266;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "5zU4CJby_FoQkoqpzgM";
var google_remarketing_only = false;
/* ]]> */
</script>
<script type="text/javascript" src="//www.googleadservices.com/pagead/conversion.js">
</script>
<noscript>
<div style="display:inline;">
<img height="1" width="1" style="border-style:none;" alt="" src="//www.googleadservices.com/pagead/conversion/969557266/?label=5zU4CJby_FoQkoqpzgM&guid=ON&script=0"/>
</div>
</noscript>
{% endblock %}
You have not passed the signup_form to the template.
return render_to_response(template_name, {'signup_form': signup_form}, context_instance=RequestContext(request))
I have no idea what locals() does.
Edit: I just saw locals which is a built in python function. It will be better if you explicitly pass the variables you need in the template.
Edit 2: Check if it is the correct template_name. In the template simply print and see the form {{ signup_form }}. See if it is available.
You are not returning the form.
Try changing the last line of the view to
return render_to_response(template_name, locals(), context_instance=RequestContext(request, {'signup_form' : signup_form ))