I am having trouble with sending flashed messages to a route that extends its layout from another template. This message shows up just fine if use the message in the layout.html which makes me believe that rendering login.html first will render layout.html and use the flashed message there and not pass it to my /login route. How are you able to call this message in an extended template? I am using the jijna with syntax taken from here to be able to have the message variable available within my mainblock. Flask's documentation does not specify this either.
app.py
#app.route("/login", methods=["POST", "GET"])
def login():
# Forget any previous user
if session.get("user_id"):
session.pop("user_id")
if request.method == "POST":
# Create connection cursor
cursor = mysql.connection.cursor()
# Query database for email
cursor.execute("SELECT id, email, password FROM users WHERE email = %s", [request.form.get("email")])
row = cursor.fetchone()
print(row)
if row is None:
print("WHY")
flash("Invaid user")
return redirect("login")
My layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hoook - {% block title %}{% endblock %}</title>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, width=device-width">
<link href="/static/favicon-16x16.png" rel="icon">
<link href="/static/style.css" rel="stylesheet">
<!-- Scripts -->
<script src="https://kit.fontawesome.com/542c2d099e.js" crossorigin="anonymous"></script>
<script src="/static/mainJS.js"></script>
</head>
<body>
<div class="page-wrapper">
<header>
<nav class="main-navbar">
{% if request.path == "/login" %}
<div class="navbar-container login-container">
{% else %}
<div class="navbar-container">
{% endif %}
<div>
{% if request.path == "/login" %}
<img src="/static/hoook_logo_blue.png" alt="Hoook Logo" height="50" width="150">
{% else %}
<img src="/static/hoook_logo.png" alt="Hoook Logo" height="50" width="150">
{% endif %}
</div>
{% if request.path != "/login" %}
<div>
{% if session["user_id"] %}
{# change nav bar for logged in users #}
{% else %}
{# work on this nav bar for unlogged in users #}
{% if request.path == "/signup" %}
<a class="navbar-link" href="/login">Sign in</a>
{% endif %}
{% endif %}
</div>
{% endif %}
</div>
</nav>
</header>
</div>
<main>
{% if request.path == "/login" %}
<div class="top-container signup-container">
{% else %}
<div class="top-container">
{% endif %}
{% with messages = get_flashed_messages() %}
{% block main %}{% endblock %}
{% endwith %}
</div>
</main>
<footer>
</footer>
</body>
</html>
My login.html
{% extends "layout.html" %}
{% block title %}
Login
{% endblock %}
{% block main %}
<div class="login-div">
<div>
<h1 class="color-control">Sign in to Hoook</h1>
</div>
<div class="login-input-bx">
<form action="/login" method="post" autocomplete="off">
<div class="form-control login-form-control">
<label class="login-label color-control" for="email">Email address</label>
<input class="login-input" type="text" name="email" id="email" required autofocus>
</div>
<div class="form-control login-form-control">
<label class="login-label color-control" for="password">Password</label>
<input class="login-input" type="password" name="password" id="password" required readonly onfocus="this.removeAttribute('readonly')">
</div>
<button class="btn btn-login" type="submit">Sign in</button>
</form>
</div>
{% if messages %}
{% for msg in messages %}
<div class="flashed-messages-div">
<p class="signup-para" id="login-flashed-messages">Error: {{ msg }}</p>
</div>
{% endfor %}
{% endif %}
<div class="signup-link-div">
<p class="color-control signup-login-font">New to Hoook? <a class="signup-link-anchor" href="/signup">Create an account</a>.</p>
</div>
</div>
{% endblock %}
Update
I guess I could do something like make_response instead as seen here. and just use:
response = make_response(render_template("login.html", message = "Invalid user"), 302)
return response
However I am curious if there is a way to pass the flashed message through instead.
I have had the same issue. Instead of:
return redirect("login")
try with:
return render_template("login.html")
The flashed message works that way for me.
Related
In the django basic polls app. I have added the functionality to add polls and I want the "add choice" form to come below the "poll detail" form on the template, how do i do it?
I want the "add choice" to render below the Vote of "detail" template
Add choice view:
def choice_view(request,question_id):
if request.user.is_staff and request.user.has_perm('poll.add_choice'):
question=Question.objects.get(pk=question_id)
if request.method=='POST':
cform=choice_form(request.POST)
if cform.is_valid():
add_poll=cform.save(commit=False)
add_poll.question=question
add_poll.vote=0
add_poll.save()
cform.save()
return HttpResponseRedirect(reverse('polls:add_choice',args=(question_id,)))
else:
cform=choice_form()
return render(request,'polls/add_choice.html',{'cform':cform,'question_id':question_id},context_instance=RequestContext(request),)
else:
return HttpResponse('Permission Denied')
Add choice template:
{% load crispy_forms_tags %}
{% include 'polls/base2.html' %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Add Choices</title>
</head>
<body>
<h1>Add Choices</h1>
<form method="post">
{% csrf_token %}
{{ cform.choice_text | as_crispy_field }}
<button class="btn btn-primary btn-default" type="submit">Add Next</button>
Done
</form>
</body>
</html>
Add choice form:
class choice_form(forms.ModelForm):
class Meta:
model=Choice
fields=['choice_text']
Poll detail view:
class DetailView(generic.DetailView):
model=Question
template_name = 'polls/detail.html'
Poll detail template:
{% load staticfiles %}
{% include 'polls/base2.html' %}
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ question.question_text }}</h1>
{% if error_message %}
<p><strong>{{ error_message }}</strong></p>
{% endif %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% for choice in question.choice_set.all %}
{% if choice.is_voted_by%}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }} " checked="checked" />
{% else%}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }} " />
{% endif%}
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br/>
{% endfor %}
<br><button class="btn btn-lg btn-primary btn-block" type="submit" style="width: 100px">Vote</button>
</form>
<br>Leave a comment
{% if user.is_staff %}
Delete question
{% endif %}
<hr>
<h3>Comments</h3>
{% for comment in question.comments.all %}
<br>{{ comment.body }}
{% if user.is_staff %}
Delete comment
{% endif %}
<br>--{{ comment.email }}<br>
{% endfor %}
</body>
</html>
I'm trying to build a authentication based view! My html code is:
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<link href="{% static "css/base.css" %}" rel="stylesheet">
</head>
<body>
<div id="header">
<span class="logo">Bookmarks</span>
{% if request.user.is_authenticated %}
<ul class="menu">
<li {% if section == "dashboard" %}class="selected"{% endif %}>My dashboard</li>
<li {% if section == "images" %}class="selected"{% endif %}>Images</li>
<li {% if section == "people" %}class="selected"{% endif %}>People</li>
</ul>
{% endif %}
<span class="user">
{% if request.user.is_authenticated %}
Hello {{ request.user.first_name }}, Logout
{% else %}
Log-in
{% endif %}
</span>
</div>
</body>
</html>
Here the line:
request.user.first_name
supposed to show the logged in username according to Django By Example book.
also when I'm changing the password in firefox it shows this massage:
But in chrome it works fine in changing password, although the name is not showing in both browser!
My Login page html code is :
{% extends "base.html" %}
{% block title %}Log-in{% endblock %}
{% block content %}
<h1>Log-in</h1>
{% if form.errors %}
<p>
Your username and password didn't match.
Please try again.
</p>
{% else %}
<p>Please, use the following form to log-in:</p>
{% endif %}
<div class="login-form">
<form action="{% url 'login' %}" method="post">
{{ form.as_p }}
{% csrf_token %}
<input type="hidden" name="next" value="{{ next }}" />
<p><input type="submit" value="Log-in"></p>
</form>
</div>
{% endblock %}
I'm stuck really bad :(
This is silly! The problem was I didn't set the user's firstname!
But the second problem is still happening!
i had same issue, but after some research, i found this solution
so try to edit the variable from {{ request.user.first_name }} TO {{ request.user.username}}, so is username not firstname.
I have a second-base.html that is parent of user-image.html
when I load second-base.html I pass it some forms and all forms are reachable and every things are ok . but when I link to user-image.html that is socond-base.html 's child I cant access forms .
if any body could help me
here is my view.py
def dashboard(request):
context = RequestContext(request)
if request.method == 'GET':
questioner_form = QuestionerForm()
return render_to_response('second-level-base.html', locals(), context)
and here is my second-base.html
{% load static %}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
<title> {% block title %}{% endblock %}</title>
{% block head %} {% endblock head%}
</head>
<body>
<div class="modal fade " id="questionerModal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
<div class="modal-dialog ">
<div class="modal-content">
<div class="modal-header" >
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<form class="form col-md-12 center-block" id="questionerForm" role="form" method="post" enctype="multipart/form-data" action="{% url 'Questioner' %}">
{% csrf_token %}
<div class="form-group">
{{questioner_form.as_p}}
</div>
</form>
</div>
</div>
</div>
and here is part of my inhirented userimage.html which to needs access forms which passed to it's parent ( second-base.html)
{% extends 'second-level-base.html' %}
{% load static %}
{% block title %} User Image {% endblock %}
{% block body %}
{{questioner_form.as_p}}
{% endblock %}
</body>
</html>
From https://docs.djangoproject.com/en/dev/topics/forms/#reusable-form-templates I can see that you have to use include to make the forms of your second-base.html's template available to userimage.html.
I'm quite new to Django and I have a problem that I cannot solve for a long time already. Would appreciate any hint!
The question is why does it find static files for base.html and cannot find it for login.html(they are even in the same directory)? Everything works fine, django manages to find template "index.html", which extends "base.html" and shows it with a nice bootstrap example. However, when I click login, and go to accounts/login (I use django-allauth), I get the error:
"GET /accounts/login/static/twitter_bootstrap/dist/css/bootstrap.css HTTP/1.1" 404 7044
"GET /accounts/login/static/twitter_bootstrap/dist/js/bootstrap.js HTTP/1.1" 404 7038
Thus, it doesn't load bootstrap and js.. I tried so many workarounds, debug shows that it points to correct path.. The processes of login/logout/etc. work fine.
What I want to do is to define in base.html that I want to use bootstrap files, and then simply extend this behavior to other templates as well. Can someone help, please?
My static files live in the project folder under static name.
-Project Dir
-static
-static
-twitter_bootstrap
-static-only
-media
-templates
-account
-base.html
-login.html
-signups(app name)
-index.html
settings.py
BASE_DIR = os.path.dirname(__file__)
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static", "static-only")
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static", "media")
STATICFILES_DIRS = (
os.path.join(os.path.dirname(BASE_DIR), "static", "static"),
)
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(BASE_DIR), "static", "templates"),
)
Base.html:
{% load url from future %}
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
{% block headbootstrap %}
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Basic css -->
<link href="static/twitter_bootstrap/dist/css/bootstrap.css" rel="stylesheet">
{% endblock %}
<title>{% block head_title %}{% endblock %}</title>
{% block extra_head %}
{% endblock %}
</head>
<body>
{% block header %}
<div class="navbar navbar-fixed-top navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-header">
<!-- Mobile Nav Button -->
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- END Mobile Nav Button -->
<a class="navbar-brand" href="#">HumanPulse</a>
</div>
<!-- Navigation Links -->
<div class="collapse navbar-collapse">
{% if request.user.is_authenticated %}
<!—Show Home and News -->
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>News</li>
</ul>
{%else%}
<!—Show Dashboard and Data -->
<ul class="nav navbar-nav">
<li class="active">Dashboard</li>
<li>Data</li>
</ul>
{% endif %}
<!-- END Navigation Links -->
<form class="navbar-form navbar-right" role="form" method="post" action="{% url 'account_login' %}">
{% csrf_token %}
{{ form.non_field_errors }}
{% if request.user.is_authenticated %}
<a class="btn btn-success" type="submit" href="/accounts/logout/" >Logout</a>
{% if request.user.first_name or request.user.last_name %}
{{ request.user.first_name }} {{ request.user.last_name }}
{% else %}
{{ request.user.username }}
{% endif %}
{% if request.user.profile.account_verified %} (verified) {% else %} (unverified) {% endif %}
{% else %}
<a class="btn btn-success" type="submit" href="/accounts/login/" >Login</a>
{% endif %}
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
</form>
</div><!-- /.nav-collapse -->
</div><!-- /.container -->
</div><!-- /.navbar -->
{% endblock %}
{% block body %}
<div class="container">
<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron">
<h1>Navbar example</h1>
<p>This example is a quick exercise to illustrate how the default, static and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.</p>
<p>To see the difference between static and fixed top navbars, just scroll.</p>
<p>
<a class="btn btn-lg btn-primary" href="../../components/#navbar" role="button">View navbar docs »</a>
</p>
</div>
</div> <!-- /container -->
<div class="container">
{% block content %}
{% endblock %}
</div> <!-- /container -->
{% endblock %}
{% block extra_body %}
{% endblock %}
{% block footer %}
<footer>
<p>© Blog 2013</p>
</footer>
{% endblock %}
<script src="static/twitter_bootstrap/dist/js/bootstrap.js"></script>
index.html
{% extends 'account/base.html' %}
{% block head_title %}ProjectName{% endblock %}
{% block content %}
<p>Voila!</p>
{% endblock %}
login.html
{% extends "account/base.html" %}
{% load i18n %}
{% block head_title %}{% trans "Sign In" %}{% endblock %}
{% block content %}
<div class="fb"></div>
{% include "socialaccount/snippets/login_extra.html" %}
<div class="inset">
<div class="header">Or sign in directly</div>
<form class="login" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
{{ form.non_field_errors }}
<input id="id_login" class="login-input" maxlength="30" name="login" placeholder="Username" type="text" />{{ form.login.errors }}<br>
<input id="id_password" class="login-input" name="password" placeholder="Password" type="password" />{{ form.password.errors }}<br>
<div class="remember-forgot-section">
<input id="id_remember" name="remember" type="checkbox" />
<label for="id_remember">Remember Me</label>
<a class="forgot" href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
</div>
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
<button class="btn" type="submit">{% trans "Sign In" %}</button>
</form>
<div class="footnote">
Don't have an account? Login with Facebook above or Sign Up
</div>
</div>
{% endblock %}
I would like to show the number of unreaded msgs in User Panel Box which will appear everytime when user is logged in.
How to pass the number of msg from controler to the user panel box which is included in base layout?
I can't use routes for that because the panel appears on all pages (index as well).
Now i'm sending it using global session but i think it could be done better. Any clues ?
Controler:
if(isset($_SESSION['user_id'])){
$unreaded=Model::factory('Message')->filter('getUnreadedGroups',$_SESSION['user_id']);
$_SESSION['unreaded']=$unreaded->opened;}
Base layout
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="/css/reset.css" />
<link rel="stylesheet" href="/css/style.css" />
<title>{% block page_title %} {% endblock %}</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="/js/jquery.scripts.js"></script>
</head>
<body>
<div id="all">
<div id="top-container">
<div id="logo">test</div>
<div id="search-box"></div>
</div>
<div id="left-side">
<div class="menu">
<ul>
<li class="nav_dashboard active">Strona główna</li>
<li class="nav_graphs">Wzory</li>
<li class="nav_forms">Najnowsze</li>
<li class="nav_typography">Najlepiej oceniane</li>
</ul>
</div>
</div>
<div id="page">
{% block content %} {% endblock %}
</div>
<div id="right-side">
<div id="login-container">
{% if session.user_id is defined %}
{% include 'user_panel.php' %}
{% else %}
{% include 'login_form.php' %}
{% endif %}
</div>
</div>
</div>
</body>
</html>
User Panel Box
<div class="login-top" id="login-form-top">
<div id="welcome">Witaj, <span>John Doe</span></div>
<p id="last-login">Ostatnie logowanie:</p>
<div id="logout-msg-container">
<div class="logut">Wyloguj</div>
<a id="msg-number" href="/profil/wiadomosci">
<span class="number">
{% if session.unreaded >0 %}
{{ session.unreaded }}
{% else %} 0
{% endif %}
</span>
</a>
</div>
</div>
<div class="menu">
<p class="header">Profil użytkownika</p>
<ul>
<li>Twoje Dane</li>
<li>Twoje zbiory</li>
<li>Twoje wiadomości</li>
</ul>
</div>
Typical template
{% extends 'layout.php' %}
{% block page_title %}Najnowsze pliki{% endblock %}
{% block content %}
<div id="page-top">
<h1>Najnowsze</h1>
<p>+ <span class="blue">12</span> wzorów</p>
</div>
<div id="main-topvote">
<div class="title">Najnowsze<span>( ostatni tydzień )</span></div>
<div class="content">
{% for file in files %}
<p>{{ file.idFile }}<br/> {{ file.date_add }}<br/> {{ file.desc }}<br/> {{ file.title }}<br/><br/></p>
{% else %}
<p>There are currently no articles.</p>
{% endfor %}
</div>
</div>
{% endblock %}
I havent tested this ( https://github.com/fabpot/Twig/issues/293 ):
Base layout:
...
<div id="right-side">
{% block side %}
{% block side-login %}
{% if session.user_id is defined %}
{% include 'user_panel.php' %}
{% else %}
{% include 'login_form.php' %}
{% endif %}
{% endblock %}
{% endblock %}
</div>
...
Typical template:
...
{% block side %}
{% set count = 12 %}
{% block side-login %}
{{ parent() }}
{% endblock %}
{% endblock %}
...
So you can use {{count}} in your User Panel Box.
You can also try to skip the side-login block definition .. but i am not sure.