User is never authenticated even when the user is logged in. Right sidebar always displays Not Loggedin.Do i need to return something to base.html? And how will i do that ? do i need a new function in views.py ? but there is no url for base.hthl. What i am missing?Please be specific i am in web dev. PS: i also tried if request.user.is_loggedin and some other
base.html
<div id="sidebar">
{% block sidebar %}
<ul>
<li>Notes</li>
</ul>
{% endblock %}
</div>
<div id="rightsidebar">
{% block rightsidebar %}
{% if request.user.is_authenticated %}
Loggedin
{% else %}
Not Loggedin
{% endif %}
{% endblock %}
</div>
<div id="content">
{% block content %}This is the content area{% endblock %}
</div>
views.py
def auth_view(request):
username = request.POST.get('username','')
password = request.POST.get('password','')
user = auth.authenticate(username = username, password = password)
if user is not None:
if user.is_active:
auth.login(request,user)
return HttpResponseRedirect('/accounts/loggedin')
else:
return HttpResponseRedirect('/accounts/auth_view')
else:
return HttpResponseRedirect('/accounts/invalid')
To be able to use
{% if request.user.is_authenticated %}
You need to do the following in you view:
from django.template import RequestContext
def view(request):
my_data_dictionary = {}
# code here
return render_to_response('template.html',
my_data_dictionary,
context_instance=RequestContext(request))
def view(request):
# code here
return render_to_response('template.html', {},
context_instance=RequestContext(request))
Because you need to use context processors.
Related
None of the other answers on this seem to solve my problem. I am trying to display a greeting that says "Welcome to the app [user]" when someone logs in. I am not sure how to get the greet page to display this message.
Here is my login function
#app.route("/login2", methods=["POST", "GET"])
def login():
if request.method == "POST":
session.permanent = True
user=request.form["nm"]
session["user"] = user
return render_template("greet.html")
else:
if "user" in session:
return redirect(url_for("greet"))
return render_template("login2.html")
Here is my login.html page
{% extends "base.html" %}
{% block title %}Log In Page{% endblock %}
{% block content %}
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for msg in messages %}
<p>{{msg}}</p>
{% endfor %}
{% endif %}
{% endwith %}
<form action="#" method="post">
<p>Name: </p>
<p><input type="text", name="nm" /></p>
<p><input type="submit", value="submit" /></p>
</form>
{% endblock %}
And here is greet.html, which should display the message that I want.
{% extends "base.html" %}
{% block content %} <h1>Welcome</h1>
<p>Hi, Welcome to the app {{}} .</p>
{% endblock %}
I believe that I need to pass something into the {{}} on the greet.html page, but I do not know what to pass in here.
In your login route when the method is POST pass the user object to the template.
#app.route("/login2", methods=["POST", "GET"])
def login():
if request.method == "POST":
session.permanent = True
user=request.form["nm"]
session["user"] = user
return render_template("greet.html", user=user)
else:
if "user" in session:
return redirect(url_for("greet"))
return render_template("login2.html")
Now you can use it in the template
<p>Hi, Welcome to the app {{user.name}} .</p>
I'm trying to flash messages in Flask using flash(), but the messages aren't appearing on the page. It isn't in the source code for the page either when looking at it with Dev Tools.
Here is the code that I have in my base.html It is outside of the blocks:
{% with messages = get_flashed_messages(with_categories=true) %}
<p>1</p>
{% if messages %}
<p>2</p>
{% for message, category in messages %}
<p>3</p>
{% if category == 'success' %}
<p>4</p>
<div class='message success'>
<p>{{ message }}</p>
</div>
{% elif category == 'error' %}
<div class='message error'>
<p>{{ message }}</p>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endwith %}
Python code(shortened to include relevant bits)
#app.route('/suggestion', methods=['GET', 'POST'])
def suggestion():
if request.method == 'POST':
...
content = f'Name: {name}\nEmail: {email}\nQuestion: {question}\nAnswer: {answer}\nType: {type}\nTopic: {topic}'
if sensible == 'Agreed' and accurate == 'Agreed':
email = Email()
sent = email.sendEmail(content)
if sent:
flash('Suggestion submitted successfully', category='success')
else:
flash('Error submitting suggestion. Please try again later',
category='error')
return redirect(url_for('suggest'))
Using the p tags to see where it's failing, I can tell that the {% if messages %} isn't working, but I don't know why.
I'm using flash('Message', category='success') to send the messages. I've looked at the Flask documentation and can't figure out what I'm doing wrong.
Please can someone help?
Have a look at this implementation
Routes.py
#auth.route("/login", methods=["GET", "POST"])
def login():
form = LoginForm()
if request.method == "POST":
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user is not None and user.confirm_password(form.password.data):
login_user(user)
flash("Login successful", "success")
return redirect(url_for("home.index"))
flash("Invalid email or password", "error")
return render_template("auth/login.html", form=form)
_message.html template
<div class="flash-message">
<div class="msg-wrapper">
{% with messages=get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category,message in messages %}
<p class="{{category}} message">{{message}}</p>
{% endfor %}
{% endif %}
{% endwith %}
</div>
</div>
Looping through the messages and categories in reverse
i have an app called reviews
reviews/forms.py
from django.forms import ModelForm, Textarea
from reviews.models import Review
class ReviewForm(ModelForm):
class Meta:
model = Review
fields = ['rating', 'comment']
widgets = {
'comment': Textarea(attrs={'cols': 40, 'rows': 15}),
}
reviews/views.py
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from .models import Review, Wine
from .forms import ReviewForm
import datetime
from django.contrib.auth.decorators import login_required
#login_required
def add_review(request, wine_id):
wine = get_object_or_404(Wine, pk=wine_id)
form = ReviewForm(request.POST)
if form.is_valid():
rating = form.cleaned_data['rating']
comment = form.cleaned_data['comment']
user_name = form.cleaned_data['user_name']
user_name = request.user.username
review = Review()
review.wine = wine
review.user_name = user_name
review.rating = rating
review.comment = comment
review.pub_date = datetime.datetime.now()
review.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('reviews:wine_detail', args=(wine.id,)))
return render(request, 'reviews/wine_detail.html', {'wine': wine, 'form': form})
reviews/templates/reviews/wine_detail.html
{% extends 'base.html' %}
{% load bootstrap3 %}
{% block title %}
<h2>{{ wine.name }}</h2>
<h5>{{ wine.review_set.count }} reviews ({{ wine.average_rating | floatformat }} average rating)</h5>
{% endblock %}
{% block content %}
<h3>Recent reviews</h3>
{% if wine.review_set.all %}
<div class="row">
{% for review in wine.review_set.all %}
<div class="col-xs-6 col-lg-4">
<em>{{ review.comment }}</em>
<h6>Rated {{ review.rating }} of 5 by {{ review.user_name }}</h6>
<h5><a href="{% url 'reviews:review_detail' review.id %}">
Read more
</a></h5>
</div>
{% endfor %}
</div>
{% else %}
<p>No reviews for this wine yet</p>
{% endif %}
<h3>Add your review</h3>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'reviews:add_review' wine.id %}" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form layout='inline' %}
{% buttons %}
<button type="submit" class="btn btn-primary">
{% bootstrap_icon "star" %} Add
</button>
{% endbuttons %}
</form>
{% endblock %}
base.html
{% load bootstrap3 %}
{% bootstrap_css %}
{% bootstrap_javascript %}
{% block bootstrap3_content %}
<div class="container">
<nav class="navbar navbar-default">
<div class="navbar-header">
<a class="navbar-brand" href="{% url 'reviews:review_list' %}">Winerama</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Wine list</li>
<li>Home</li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
<li>Hello {{ user.username }}</li>
<li>Logout</li>
{% else %}
<li>Login</li>
<li>Register</li>
{% endif %}
</ul>
</div>
</nav>
<h1>{% block title %}(no title){% endblock %}</h1>
{% bootstrap_messages %}
{% block content %}(no content){% endblock %}
</div>
{% endblock %}
I am getting the error at the line {% bootstrap_form form layout='inline' %} in the html file
Any idea how to fix this?
There's a few problems with your code as it stands, so I'll try to clean it up with some comments as I would write it to add a review to a wine.
#login_required
def add_review(request, wine_id):
wine = get_object_or_404(Wine, pk=wine_id)
if request.POST:
form = ReviewForm(request.POST)
else:
form = ReviewForm()
if form.is_valid():
### NO NEED FOR - already set as part of valid modelform ::: rating = form.cleaned_data['rating']
### AS WELL AS ::: comment = form.cleaned_data['comment']
### THIS IS NOT A FIELD IN YOUR FORM :::user_name = form.cleaned_data['user_name']
user_name = request.user.username
review = form.save(commit=False) # commit = False means that this instantiate but not save a Review model object
review.wine = wine
review.user_name = user_name # Why use this instead of a ForeignKey to user?
review.pub_date = datetime.datetime.now() # works as long as pub_date is a DateTimeField
review.save() # save to the DB now
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('reviews:wine_detail', args=(wine.id,))) # THIS will redirect only upon form save
return render(request, 'reviews/wine_detail.html', {'wine': wine, 'form': form})
Now, the error your seeing is most likely related to you passing request.POST to a form even if request.POST is blank; the form will attempt to set initial values but with a querydict that has no values that actually relates to the form.
EDIT: In response to your comments, my next step would be to try and render each form field individually and see if I can trigger a failure.
Instead of {% bootstrap_form form layout='inline' %}, try-
{% for field in form %}
{% bootstrap_field field %}
{% endfor %}
If this is an error with the django-bootstrap library trying to render the textarea widget and the inline style together (as I would suspect at this point), you can also eliminate the widget parameter and see if there's a fix. If there is, I'd suggest overriding your modelform's init method for assign a widget post a call super on init.
In Class Base View
This error may occur when you use form_class in the wrong generic view.
⮕ Open your views.py then check to see if you have set the wrong generic view in your class.
Example
class ProfileUpdateView(T̶e̶m̶p̶l̶a̶t̶e̶V̶i̶e̶w̶ UpdateView):
model = User
form_class = forms.ProfileForm
success_url = reverse_lazy("stories:story_list")
template_name = 'profile.html'
def get_object(self, queryset=None):
return get_object_or_404(User, pk=self.request.user.id)
I am in the process of making a edit listing system for my website and have run into an issue, the problem I am having is with my edit listing portal which displays all the listings associated with the relevant account. The idea is that people can click on any of the listings and it will take them to the edit listing form, however my edit listing form is suppose to be given a public key when you click on it. My problem is I dont know how to put the listings pk into the url. Could somebody please advise me on what to do?
Thanks
Code -
Listings Portal -
{% extends "base.html" %}
{% block content %}
<h1 class="pageheader">Edit Your Job Listings</h1>
<div class="joblistings">
<p class="jobcounter">There are <b>{{ joblistings.count }}</b> jobs available</p>
{% if joblistings %}
{% for joblisting in joblistings %}
{% if joblisting.active_listing %}
<div class="listings-item">
<a href="{% url 'editlisting' %}"> <--- THIS IS THE URL
<ul>
<li class="listing-title">{{ joblisting.job_title }} - {{ joblisting.business_name }}</li>
<li>Region: {{ joblisting.business_address_suburb }}</li>
<li>Pay Rate: ${{ joblisting.pay_rate }}</li>
<li>Contact Method: {{ joblisting.contact_method }}</li>
</ul>
</a>
</div>
{% endif %}
{% endfor %}
{% else %}
<p>Unfortunately all of the job opportunities have been taken at this moment.</p>
{% endif %}
</div>
{% endblock %}
Edit Listing View -
# This is the view which manages the edit listing page
#login_required(redirect_field_name='login')
def editlisting(request, pk):
post = JobListing.objects.get(pk=pk)
#if str(request.user) != str(post.user):
# return redirect("index")
if request.method == "POST":
print("test")
form = JobListingForm(request.POST, instance=post, force_update=True)
if form.is_valid():
form.save()
return redirect('index')
else:
print("else")
form = JobListingForm(instance=post)
context = {
"form": form
}
return render(request, "editlisting.html", context)
How about this?
Click me
i want to use loged in user information in my base template
{% if request.user.username %}
Logout
{% else %}
Login
{% endif %}
from django.template import RequestContext
def top(request):
return render_to_response('top.html',{}, context_instance=RequestContext(request))
If you're just wanting to check if they're logged in to display the login or logout links, I would use is_authenticated instead
{% if user.is_authenticated %}
Logout
{% else %}
Login
{% endif %}
If you are wanting to use information from the user, you can use the variables in the user class {{ user.username }}
{% if user.is_authenticated %}
Hi, {{ user.first_name }}, Logout
{% else %}
Login
{% endif %}
I use code with this structure in my base.html and it works well. I don't have anything in the template_content_processor - it works in the template on its own.