I am trying to display certain information on a template. Everything in the python code works perfectly but anything and everything inside the for loop is not getting displayed inside the template. I believe that I have passed everything correctly. Could someone please help me to display the tutor info in my 'display.html'? I also want to mention that whatever I am trying to display should be available for all users to see and not just me. The file will keep getting updated as more and more users register as a tutor. This should update and show everyone who has signed up to all the users. Code will be below. Thanks in advance!
main.py
#main.py
from flask import Flask, request, session, render_template, redirect, url_for, flash, get_flashed_messages
from flask.globals import current_app
from flask_login import LoginManager, login_user, login_required, logout_user, current_user, UserMixin
from datetime import timedelta, datetime
from werkzeug.security import generate_password_hash, check_password_hash
import sqlite3
from os import error, path
from flask_sqlalchemy import SQLAlchemy
from flask_mail import Mail, Message
app = Flask(__name__)
DB_NAME = "spark.db"
app.config["SECRET_KEY"] = "1986319249872139865432"
app.config['SQLALCHEMY_DATABASE_URI'] = f"sqlite:///{DB_NAME}"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
db.init_app(app)
def create_database(app):
if not path.exists(DB_NAME):
db.create_all(app=app)
print("Created Database!")
class Tutor(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
tremail = db.Column(db.String(10000))
trusername = db.Column(db.String(1200))
subjects = db.Column(db.String(1200))
session_length = db.Column(db.String(1200))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(150), unique=True)
username = db.Column(db.String(150))
password = db.Column(db.String(150))
tutors = db.relationship('Tutor')
create_database(app)
login_manager = LoginManager()
login_manager.login_view = 'login'
login_manager.init_app(app)
#login_manager.user_loader
def load_user(id):
return User.query.get(int(id))
#app.route("/")
#login_required
def home():
return render_template("index.html")
#app.route("/login", methods=["GET", 'POST'])
def login():
if request.method == "POST":
email = request.form.get('email')
password = request.form.get('password')
user = User.query.filter_by(email=email).first()
if user:
if check_password_hash(user.password, password):
flash('Login successful!', category="success")
login_user(user, remember=True)
return redirect(url_for("home"))
else:
flash('Incorrect password! Please try again.', category="error")
else:
flash("Account does not exist. Please register to continue.", category="error")
return render_template("login.html", user=current_user)
#app.route("/register", methods=["GET", "POST"])
def register():
if request.method == 'POST':
email = request.form.get('email')
username = request.form.get('username')
password1 = request.form.get('password1')
password2 = request.form.get('password2')
user = User.query.filter_by(email=email).first()
if user:
flash("Email already exists.", category="error")
elif len(email) < 4:
flash("Email must be greater than 3 characters.", category="error")
elif len(username) < 2:
flash("Username must be greater than 1 character.", category="error")
elif password1 != password2:
flash("Passwords do not match! Please try again.", category="error")
elif len(password1) < 8:
flash("Password must be greater than 7 characters.", category="error")
else:
new_user = User(email=email, username=username, password=generate_password_hash(password1, method='sha256'))
db.session.add(new_user)
db.session.commit()
login_user(new_user, remember=True)
flash("Account successfully created!", category="success")
return redirect(url_for('home'))
return render_template("register.html", user=current_user)
#app.route("/logout")
#login_required
def logout():
logout_user()
flash("Logged out succcessfully!", category="success")
return redirect(url_for('login'))
#app.route("/selection")
#login_required
def selection():
return render_template("selection.html")
#app.route("/tutorform", methods=['GET', 'POST'])
#login_required
def tutorform():
if request.method == 'POST':
tremail = request.form.get('tremail')
trusername = request.form.get('trusername')
subjects = request.form.get('subjects')
session_length = request.form.get('session_length')
new_tutor = Tutor(user_id=current_user.id, tremail=tremail, trusername=trusername, subjects=subjects, session_length=session_length)
db.session.add(new_tutor)
db.session.commit()
flash('Entry has been saved!', category='success')
return redirect(url_for("display"))
return render_template("tutorform.html", user=current_user)
#app.route("/tutoreeform", methods=['GET', 'POST'])
#login_required
def tutoreeform():
if request.method == 'POST':
flash("Tutoree Entry Successful!", category='success')
return redirect(url_for("display"))
return render_template("tutoreeform.html")
#app.route("/display")
#login_required
def display():
users = Tutor.query.all()
for user in users:
print(user.tremail)
print(user.trusername)
print(user.subjects)
print(user.session_length)
return render_template("display.html", users=users)
if __name__ == '__main__':
db.create_all()
app.run(debug=True)
display.html
{% extends "base.html" %}
{% block title %}SparkWIT | | Available Tutors{% endblock %}
{% block content %}
<center><h1 style="color: beige; background-color: rgba(54, 65, 165, 0.466);"><b><i>Available Tutors</i></b></h1></center>
<table class="table">
<thead>
<tr>
<th scope="col" style="color: beige;"> Tutor Emails</th>
<th scope="col" style="color: beige;">Username</th>
<th scope="col" style="color: beige;">Subjects</th>
<th scope="col" style="color: beige;">Session Length</th>
</tr>
</thead>
{% for user in users.tutors %}
<tbody>
<tr>
<td style="color: beige;">{{ user.tremail }}</td>
<td style="color: beige;">{{ user.trusername }}</td>
<td style="color: beige;">{{ user.subjects }}</td>
<td style="color: beige;">{{ user.session_length }}</td>
</tr>
</tbody>
{% endfor %}
</table>
{% endblock %}
tutorform.html
{% extends "base.html" %}
{% block title %}SparkWIT | | Tutor Registration{% endblock %}
{% block content %}
<form method="POST">
<center><h3 style="color: beige; background-color: rgba(54, 65, 165, 0.466);"><i><u>Tutor Entry</u></i></h3></center>
<div class="form-group">
<label for="tremail" style="color: azure;"><b>Email</b></label>
<input
type="email"
class="form-control"
id="tremail"
name="tremail"
placeholder="example#example.com"
required />
</div>
<div class="form-group">
<label for="trusername" style="color: azure;"><b>Username</b></label>
<input
type="text"
class="form-control"
id="trusername"
name="trusername"
placeholder="Username"
required />
</div>
<div class="form-group">
<label for="subjects" style="color: azure;"><b>Subject</b></label>
<input
type="text"
class="form-control"
id="subjects"
name="subjects"
placeholder="Ex. AP Physics"
required />
</div>
<div class="form-group">
<label for="session_length" style="color: azure;"><b>Session Length</b></label>
<input
type="text"
class="form-control"
id="session_length"
name="session_length"
placeholder="Ex. 1.5 hours"
required />
</div>
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="agree" name="agree" required>
<label class="form-check-label" for="agree" required><mark>I agree to conduct all sessions virtually for the tutoree's and my safety</mark></label>
</div>
<br>
<button type="submit" class="btn btn-dark">Submit</button>
</form>
{% endblock %}
In the HTML file, the for loop should be like {% for user in users %} because to display the user details, we need to loop on the data item we are passing in the render_template function as parameter.
Related
I'm not sure what is coursing the problem....
The view Insertemp.views.Insertrecord didn't return an HttpResponse object. It returned None instead.
views.py
from django.shortcuts import render
from Insertemp.models import EmpInsert
from django.contrib import messages
def Insertrecord(request):
if request.method == 'POST':
if request.POST.get('empname') and request.POST.get('email') and request.POST.get('country'):
saverecord = EmpInsert()
saverecord.empname = request.POST.get('empname')
saverecord.email = request.POST.get('email')
saverecord.country = request.POST.get('country')
saverecord.save()
messages.success(request, 'Record saved successfully...!')
return render(request, 'Index.html')
else:
return render(request, 'Index.html'),
I have change the code....
from django.shortcuts import render
from Insertemp.models import EmpInsert
from django.contrib import messages
def Insertrecord(request):
if request.method == 'POST':
if request.POST.get('empname') and request.POST.get('email') and request.POST.get('country'):
saverecord = EmpInsert()
saverecord.empname = request.POST.get('empname')
saverecord.email = request.POST.get('email')
saverecord.country = request.POST.get('country')
saverecord.save()
messages.success(request, 'Record saved successfully...!')
return render(request, 'templates/Index.html', {})
else:
return render(request, 'templates/Index.html', {})
but still it doesn't display what it should...
Index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Insert new Record</title>
</head>
<body>
<h1>Create or New record Insert into MySQL(PhpMyAdmin)</h1>
<h2>Python Django web Programming</h2>
<hr>
<form method="POST">
{% cdrf_token %}
Employee Name : <input type="text" placeholder="Enter Name" name="empname" required>
Email : <input type="text" placeholder="Enter Email" name="email" required>
country : <input type="text" placeholder="Enter Country" name="country" required>
<input type="submit" value="Insert record">
{% if messages %}
{% for message in messages %}
<h2 style="color: green;">{{message}}</h2>
{% endfor %}
{% endif %}
</form>
<hr>
</body>
</html>
You need to give default response, in example for GET requests:
def Insertrecord(request):
if request.method == 'POST':
if request.POST.get('empname') and request.POST.get('email') and request.POST.get('country'):
(...)
return render(request, 'templates/Index.html', {})
else:
return render(request, 'templates/Index.html', {})
return render(request, 'templates/Index.html', {}) # new
view.py file
Since im new to flask. kindly help me out with this query
UPLOAD_FOLDER = 'static/uploads/'
app = Flask(__name__)
app.secret_key = "secret key"
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
Migrate(app, db)
#view.route('/upload_image', methods=['GET','POST'])
def upload_image():
form = upload_form()
id = current_user.id
name_to_update = Users.query.get_or_404(id)
if request.method =='POST':
name_to_update.image = request.files['image']
Pic_filename = secure_filename(name_to_update.image.filename)
pic_name = str(uuid.uuid1()) + '_' + Pic_filename
saver = request.files['image']
name_to_update.image = pic_name
try:
db.session.commit()
saver.save(os.path.join(app.config['UPLOAD FOLDER'], pic_name))
flash('user profile updated successfully')
return render_template('account.html', form=form, name_to_update=name_to_update)
except:
flash('something is not working')
return render_template('account.html', form=form)
this is my account.html. i'm trying to get profile image of user and saving it to displaying in profile.
<div class="profile-content">
<div class="profile-contentimg">
<div>
<img src="static/img/apple.png" alt="" id="blah">
</div>
<form methods='POST' action="{{ url_for('view.upload_image') }}" class="dropzone">
<div class="profileupload">
<input type="file" name="filename" id="imgInp" >
<i class="fa fa-edit"></i>
<button type="submit" class="btn btn-primary">upload</button>
</div>
</form>
</div>
being beginner in programming with flask anything could be wrong.
I get an error(The view crud.views.insertEmp didn't return an HttpResponse object. It returned None instead.) whenever I try to insert data to my database through the insert.html template. I;m using postgres as my database. Any assistance in identifying the bug will be highly appreciated.
models.py
from django.db import models
class Employee(models.Model):
emp_name = models.CharField(max_length=100)
email = models.CharField(max_length=100)
occupation = models.CharField(max_length=100)
salary = models.IntegerField()
gender = models.CharField(max_length=1)
class Meta:
db_table = 'employee'
views.py
from django.shortcuts import render, redirect
from crud.models import Employee
from django.contrib import messages
def showEmp(request):
employee = Employee.objects.all()
context = {"data": employee}
return render(request, "index.html", context)
def insertEmp(request):
if request.method == "POST":
if request.POST.get('emp_name') and request.POST.get('email') and request.POST.get('occupation') and request.POST.get('salary') and request.POST.get('gender'):
saveRecord = Employee()
saveRecord.emp_name = request.POST.get('emp_name')
saveRecord.email = request.POST.get('email')
saveRecord.occupation = request.POST.get('occupation')
saveRecord.salary = request.POST.get('salary')
saveRecord.gender = request.POST.get('gender')
saveRecord.save()
messages.success(request, "Employee " +
saveRecord.emp_name + " is added succesfully.")
return render(request, "insert.html")
else:
return render(request, "insert.html")
inser.html
<center>
<h1>Insert data into Postgresql</h1>
<hr>
<form method="POST">
{% csrf_token %}
<table border="">
<tr>
<td>Employee Name</td>
<td><input type="text" placeholder=" Enter employee name.." name="emp_name""></td>
</tr>
<tr>
<td>Email</td>
<td><input type=" text" placeholder="Enter email" name="email">
</td>
</tr>
<tr>
<td>Occupaton</td>
<td>
<select name="occupation">
<option selected disabled=true>-- Select occupation --</option>
<option value="">Programmer</option>
<option value="">HR</option>
<option value="">Sales Manager</option>
<option value="">Designer</option>
</select>
</td>
</tr>
<tr>
<td>Salary</td>
<td><input type="text" placeholder="Enter salary" name="salary"></td>
</tr>
<tr>
<td>Gender</td>
<td>
<input type="radio" name="gender" value="M">Male |
<input type="radio" name="gender" value="F">Female
</td>
</tr>
<tr>
<td><input type="submit" value="Insert"></td>
<td>
{% if messages %}
{% for message in messages %}
<b style="color:green;">{{message}}</b>
{% endfor %}
{% endif %}
</td>
</tr>
</table>
</form>
</center>
The way you structure your code may cause the return of None, try to follow this example :
from django.shortcuts import render, redirect
def insertEmp(request):
if request.method == "POST":
if request.POST.get('emp_name') and request.POST.get('email') and request.POST.get('occupation') and request.POST.get('salary') and request.POST.get('gender'):
saveRecord = Employee()
saveRecord.emp_name = request.POST.get('emp_name')
saveRecord.email = request.POST.get('email')
saveRecord.occupation = request.POST.get('occupation')
saveRecord.salary = request.POST.get('salary')
saveRecord.gender = request.POST.get('gender')
saveRecord.save()
messages.success(request, "Employee " +
saveRecord.emp_name + " is added succesfully.")
# Redirect to the same page (you can change the page to fit your needs)
return redirect('.')
else:
# Not all required fields are present
messages.error(request, "Please fill all the fields")
# Also redirect the user to the same page
return redirect('.')
else:
return render(request, "insert.html")
I have a simple form with a password field in Flask that should have a limited amount of chances (10) to submit correctly. The problem is that even though I am subtracting the chances variable by 1 every time the submitted value isn't correct, chances is only subtracted once (it stops at 9), no matter how many times I submit the form and refresh the page.
Here's my route:
#app.route('/administrator-login', methods=['GET','POST'])
def admin_login():
if current_user.is_authenticated:
return redirect('/administrator-logout')
form = AdminLogin()
user = User.query.first()
if form.validate_on_submit():
if user.chances <= 0:
return render_template(url_for('home'))
if user and form.password.data == 'password': # I will hash the actual password later
user.chances = 10
login_user(user)
return redirect('/hack-the-site-here')
elif form.password.data != 'password':
user.chances -= 1
return render_template('admin_login.html', form=form, chances=user.chances)
And here's my form:
class AdminLogin(FlaskForm):
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Login')
The 'admin_login.html' file
<h3>Chances left: {{ chances }}</h3>
<div class="mt-3">
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Admin Login</legend>
<div class="form-group">
{{ form.password.label(class="form-control-label") }}
{% if form.password.errors %}
{{ form.password(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.password.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.password(class="form-control form-control-lg") }}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info btn-lg") }}
</div>
</form>
</div>
</div>
And this is the User class:
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
chances = db.Column(db.Integer)
There is only one User object in the database and that shouldn't change.
Criticism and advice are accepted.
I suspect that it has something to do with the way that user.chances is stored in the User object.
Do you need any other information? Thanks in advance.
You need to update the value of the chance in DB also after making changes in the chances attribute.
#app.route('/administrator-login', methods=['GET','POST'])
def admin_login():
if current_user.is_authenticated:
return redirect('/administrator-logout')
form = AdminLogin()
user = User.query.first()
if form.validate_on_submit():
if user.chances <= 0:
return render_template(url_for('home'))
if user and form.password.data == 'password': # I will hash the actual password later
user.chances = 10
db.session.commit()
login_user(user)
return redirect('/hack-the-site-here')
elif form.password.data != 'password':
user.chances -= 1
db.session.commit()
return render_template('admin_login.html', form=form, chances=user.chances)
I have a table on my webpage that I want to iterate product information into and it worked up until I tried adding a paginator. The server runs fine and the rest of the website is functional.
Here are my files:
shop/products.html
{% extends 'base.html' %}
{% block content %}
<h1>On sale here</h1>
<div class="col-sm-3">
<h4>Categories</h4>
<ul class="list-group">
All Categories
{% for c in countcat %}
<a href="{{ c.get_absolute_url }}" class="list-group-item catheight">{{c.name}}
<span class="badge">{{c.num_products}}</span>
</a>
{% endfor %}
</ul>
</div>
<div class="col-sm-9">
<h4>Note that all products are second hand, unless otherwise stated.</h4>
<form class="form-inline my-2 my-lg-0" action="{% url 'search_result' %}" method="get">
{% csrf_token %}
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search" name="q">
<button class="glyphicon glyphicon-search h-100" type="submit"></button>
</form>
<table class="table table-bordered table-hover table-condensed">
<thead>
<!-- The header row-->
<tr>
<th>ID</th>
<th>Name</th>
<th>Image</th>
<th>Category</th>
<th>Description</th>
<th>Stock</th>
<th>Price</th>
<th>Buy</th>
</tr>
</thead>
<tbody>
<!-- Product row(s) -->
{% for product in products %}
<tr>
<td>{{product.id}}</td>
<td>{{product.name}}</td>
{% if product.image %}
<td><img src="{{product.image.url}}"></td>
{% endif %}
<td>{{product.category}}</td>
<td>{{product.description}}</td>
<td>{{product.stock}}</td>
<td>€{{product.price}}</td>
{% if product.stock > 0 %}
<td><a href="{% url 'add_cart' product.id %}" class="btn btn-default btn-xs"><span
class="glyphicon glyphicon-shopping-cart"></span></a></td>
{% else %}
<td><a href="" class="btn btn-default btn-xs"><span
class="glyphicon glyphicon-warning-sign red"></span></a></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
<hr>
<div class="text-center">
{% for pg in products.paginator.page_range %}
<a href="?page={{pg}}" class="btn btn-light btn-sm
{% if products.number == pg %}
active
{% endif %}">{{pg}}</a>
{% endfor %}
</div>
</div>
{% endblock content %}
shop/models.py
from django.db import models
from django.urls import reverse
class Category(models.Model):
name = models.TextField()
products = models.ManyToManyField('Product')
def get_products(self):
return Product.objects.filter(category=self)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('product_list_by_category',args=[self.id])
class Product(models.Model):
name = models.TextField()
description = models.TextField()
stock = models.IntegerField()
price = models.DecimalField(max_digits=10,decimal_places=2)
image = models.ImageField(upload_to='images/', blank=True)
def __str__(self):
return self.name
shop/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.product_list,
name='products'),
path('<int:category_id>/', views.product_list,
name='product_list_by_category'),
]
shop/views.py
from django.shortcuts import render, get_object_or_404, redirect
from .models import Category, Product
from django.db.models import Count
from django.contrib.auth.models import Group, User
from .forms import SignUpForm
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth import login, authenticate, logout
from django.core.paginator import Paginator, EmptyPage, InvalidPage
def product_list(request, category_id=None):
category = None
products = Product.objects.all()
ccat = Category.objects.annotate(num_products=Count('products'))
if category_id :
category = get_object_or_404(Category, id=category_id)
products = products.filter(category=category)
paginator = Paginator('products', 3)
try:
page = int(request.GET.get('page', 1))
except:
page = 1
try:
products = paginator.page(page)
except(EmptyPage, InvalidPage):
products = paginator.page(paginator.num_pages)
return render(request, 'products.html',
{'products': products,
'countcat':ccat})
def signupView(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get("username")
signup_user = User.objects.get(username=username)
customer_group = Group.objects.get(name= 'Customer')
customer_group.user_set.add(signup_user)
else:
form = SignUpForm()
return render(request, 'accounts/signup.html', {'form':form})
def signinView(request):
if request.method == 'POST':
form = AuthenticationForm(data=request.POST)
if form.is_valid():
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect('products')
else:
return redirect('signup')
else:
form = AuthenticationForm()
return render(request, 'accounts/signin.html', {'form':form})
def signoutView(request):
logout(request)
return redirect('signin')
I'm sort of a django noob so any help would be greatly appreciated, thanks :)
You are passing a string to Paginator here:
paginator = Paginator('products', 3)
You should pass an object_list:
paginator = Paginator(products, 3)