How to display user name from collection not form in flask? - python

I am trying to display the name of users after the login only using email and password as input. Users already have their names, email, and password within the collection in which of course I can use all of them to authenticate within a login form with three inputs.
But trying to use a session to retrieve data from the collection and form authenticating from the form with the collection I am having issues to display the session['name'] in the seller central after the login.
I have already used an if statement to pass the name within the session but I think I am doing it wrong.
Login function:
#app.route('/login', methods=['POST', 'GET'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
user = mongo.db.user
login_user = user.find_one({
#'name': request.form.get('username'),
'email': request.form.get('email'),
'password':request.form.get('password'
)})
if login_user:
session['email'] = request.form.get('email')
session['name'] = mongo.db.user.find_one({'name': 'name'})
return redirect(url_for('user'))
return 'Invalid username or password combination'
Login form:
{% extends 'layout.html' %} {% block content %}
<div class="row justify-content-center card-deck">
<div class="col-md-4 card card-body">
<!-- Vertical navbar -->
{% if session['email'] != None %}
<div class="vertical-nav bg-white" id="sidebar">
<div class="py-4 px-3 mb-4 bg-light">
<div class="media d-flex align-items-center"><img src="https://res.cloudinary.com/mhmd/image/upload/v1556074849/avatar-1_tcnd60.png" alt="..." width="65" class="mr-3 rounded-circle img-thumbnail shadow-sm">
<div class="media-body">
<h4 class="m-0">{{ session['name'] }}</h4>
<p class="font-weight-light text-muted mb-0">Seller</p>
</div>
</div>
</div>
<p class="text-gray font-weight-bold text-uppercase px-3 small pb-4 mb-0">Main</p>
<ul class="nav flex-column bg-white mb-0">
<li class="nav-item">
<a href="#" class="nav-link text-dark font-italic bg-light">
<i class="fa fa-envelope mr-3 text-dark fa-fw"></i>
{{session['email']}}
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link text-dark font-italic bg-light">
<i class="fa fa-th-large mr-3 text-dark fa-fw"></i>
Products
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link text-dark font-italic">
<i class="fa fa-address-card mr-3 text-dark fa-fw"></i>
About
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link text-dark font-italic">
<i class="fa fa-cubes mr-3 text-primary fa-fw"></i>
Services
</a>
</li>
<li class="nav-item">
<a href="#" class="nav-link text-dark font-italic">
<i class="fa fa-comments-o mr-3 text-primary fa-fw"></i>
Comments
</a>
</li>
</ul>
<p class="text-gray font-weight-bold text-uppercase px-3 small py-4 mb-0">Charts</p>
{% endif %}
<----THE REST OF THE FORM--->
{% endblock %}
It is displaying the session['email'] but not the session['name'] in which I want to display on the user name after he or she be logged in. It must be something simple but I can't find.

Since you already select the login_user above in the code, you can directly use the members of this user object :
if login_user:
session['email'] = login_user['email']
session['name'] = login_user['name']
return redirect(url_for('user'))

Related

Django search bar isn't giving correct results

views.py
from django.shortcuts import render
from ecommerceapp.models import Product
from django.db.models import Q
def searchResult(request):
products=None
query=None
if 'q' in request.GET:
query = request.GET.get('q')
products=Product.objects.all().filter(Q(name__contains=query) | Q(desc__contains=query))
return render(request,'search.html',{'query':query,'products':products})
In views.py I have imported a model named 'Product' of another application.
search.html
{% extends 'base.html' %}
{% load static %}
{% block metadescription %}
Welcome to FASHION STORE-Your Beauty
{% endblock %}
{% block title %}
Search-FASHION STORE
{% endblock %}
{% block content %}
<div>
<p class="text-center my_search_text">You have searched for :<b>"{{query}}"</b></p>
</div>
<div class="container">
<div class="row mx_auto">
{% for product in products %}
<div class="my_bottom_margin col-9 col-sm-12 col-md-6 col-lg-4" >
<div class="card text-center" style="min-width:18rem;">
<img class="card-img-top my_image" src="{{product.image.url}}" alt="{{product.name}}" style="height:400px; width:100%;">
<div class="card_body">
<h4>{{product.name}}</h4>
<p>₹{{product.price}}</p>
</div>
</div>
</div>
{% empty %}
<div class="row mx_auto">
<p class="text-center my_search_text">0 results found.</p>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
navbar.html
<nav class="navbar navbar-expand-lg bg-light">
<div class="container-fluid">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="#">Home</a>
</li>
<li class="nav-item dropdown {% if 'ecommerceapp' in request.path %} active {% endif %} ">
<a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Shop
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'ecommerceapp:allProductCategory' %}">All Products</a></li>
{% for cat in links %}
<li><a class="dropdown-item" href="{{cat.get_url}}">{{cat.name}}</a></li>
{% endfor %}
</ul>
</li>
<li class="nav-item">
<a class="nav-link disabled" href=""><i class="fa fa-shopping-cart"></i></a>
</li>
</ul>
<form class="d-flex" action="{% url 'search_app:searchResult' %}" method="get">
{% csrf_token %}
<input class="form-control me-2" type="search" placeholder="Search" name="q" aria-label="Search">
<button class="btn btn-outline-success" type="submit"><i class="fa fa-search"></i></button>
</form>
</div>
</div>
</nav>
When I'm searching using search bar, not getting the correct results. When giving the word completely, correct results are getting.
Example: When I type x in the search bar, it give me the results 'shirt' instead of giving '0 results found'.
Example: When I type x in the search bar, it give me the results 'shirt' instead of giving '0 results found'.
The __contains is used to check whether the field contains given word or not, it is case-sensitive. And using | in Q objects means it is optional and works as OR condition, so maybe it is possible when you type x, the name field doesn't contains x but the field desc contain x that's why you are getting the shirt as instance or else you can simply put the query to Product.objects.filter(Q(name__contains=query)) and .all() only creates the copy of the Queryset so it doesn't require here.

Flask redirecting to wrong links

<nav class="navbar navbar-dark align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0">
<div class="container-fluid d-flex flex-column p-0"><a
class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="#">
<div class="sidebar-brand-icon rotate-n-15"><i class="fas fa-laugh-wink"></i></div>
<div class="sidebar-brand-text mx-3"><span>hEALTHGENIC</span></div>
</a>
<hr class="sidebar-divider my-0">
<ul class="navbar-nav text-light" id="accordionSidebar">
<li class="nav-item"><a class="nav-link active" href="/"><i
class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
<li class="nav-item"></li>
<li class="nav-item"></li>
<li class="nav-item"><a class="nav-link" href="/login"><i
class="far fa-user-circle"></i><span>Login</span></a></li>
<li class="nav-item"></li>
</ul>
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0"
id="sidebarToggle" type="button"></button></div>
</div>
</nav>
The above code waas stored in index.html.
The flask code(python) was:
from flask import Flask, render_template, request
local_server = True
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/login')
def login():
return render_template('login.html')
if __name__ == '__main__':
app.run(debug = True)
On clicking the dashboard button, the link which is returned is
/index.html instead of / . Whats the problem here?
When you creating a href's to route in Flask you should use url_for function in HTML file:
<nav class="navbar navbar-dark align-items-start sidebar sidebar-dark accordion bg-gradient-primary p-0">
<div class="container-fluid d-flex flex-column p-0"><a
class="navbar-brand d-flex justify-content-center align-items-center sidebar-brand m-0" href="#">
<div class="sidebar-brand-icon rotate-n-15"><i class="fas fa-laugh-wink"></i></div>
<div class="sidebar-brand-text mx-3"><span>hEALTHGENIC</span></div>
</a>
<hr class="sidebar-divider my-0">
<ul class="navbar-nav text-light" id="accordionSidebar">
<li class="nav-item"><a class="nav-link active" href="{{ url_for('index') }}"><i
class="fas fa-tachometer-alt"></i><span>Dashboard</span></a></li>
<li class="nav-item"></li>
<li class="nav-item"></li>
<li class="nav-item"><a class="nav-link" href="{{ url_for('login') }}"><i
class="far fa-user-circle"></i><span>Login</span></a></li>
<li class="nav-item"></li>
</ul>
<div class="text-center d-none d-md-inline"><button class="btn rounded-circle border-0"
id="sidebarToggle" type="button"></button></div>
</div>
</nav>

How to link to other user's profile in django?

What I have been trying is to click the post's author(the user that created the post) I want it to redirect me to that user's profile, for example in Instagram when you click the user that is on top of the post-it redirects you to their profile. Every time I do that instead of seeing the post's author profile I see the logged in user profile. I think there is something wrong in the views.py file or in the base.html.
views.py
def profile(request, pk=None):
if pk:
user = get_object_or_404(User, pk=pk)
else:
user = request.user
args = {'user': user}
return render(request, 'profile.html', args)
def home(request):
created_posts = Create.objects.all().order_by("-added_date")
return render(request, 'base.html', {"created_posts": created_posts})
def create(request):
if request.method == 'POST':
created_date = timezone.now()
header1 = request.POST['header']
content1 = request.POST['content']
user = request.user
created_obj = Create.objects.create(added_date=created_date, title=header1, content=content1, user=user)
created_obj.save()
print('create created')
return redirect('home')
else:
print('create not created')
return render(request, 'create.html')
models.py
class Create(models.Model):
added_date = models.DateTimeField()
title = models.CharField(max_length=200)
content = models.CharField(max_length=200)
user = models.ForeignKey(User, related_name='user', on_delete=models.CASCADE, default=1)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
def __str__(self):
return f'{self.user.username} Profile'
urls.py
urlpatterns = [
path('', views.home, name='home'),
path('profile', views.profile, name='profile'),
path('profile/<int:pk>/', views.profile, name='profile_pk'),
path('create', views.create, name='create'),
]
profile.html (shows user's profile)
{% extends 'home.html' %}
{% block body%}
<div class="content-section">
<div class="media">
<img class="rounded-circle account-img" src="{{ user.profile.image.url }}">
<div class="media-body">
<h2 class="account-heading">{{ user.username }}</h2>
<p class="text-secondary">{{ user.email }}</p>
</div>
</div>
</div>
{% endblock %}
base.html (shows all user's post with the user's username)
{% extends 'home.html' %}
{% block body %}
<ul action="{% url 'create' %}" class="container-sm list-group" style="margin-top: 200px;">
{% for created_post in created_posts %}
<li class="list-group-item">{{ created_post.title }}
{{ created_post.user }}
<p>{{ created_post.content }}</p>
<div class="float-right">
<form action="delete_create/{{ created_post.id }}/" action="post">
<button type="submit" class="btn btn-outline-danger btn-sm">Delete</button>
</form>
</div>
<div class="float-right">
Edit
</div>
</li>
{% endfor %}
</ul>
{% endblock %}
home.html (navbar that shows the loged in user)
<body>
<nav class="navbar navbar-expand-md fixed-top navbar-dark" style="background-color: rgba(0, 0, 0, 0.712);">
<div class="container">
<a class="navbar-brand" href="/">
<img src="static/style/images/logowebdev-png.png" alt="logo" style="width: 60px; height: auto;">
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExample07" aria-controls="navbarsExample07" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExample07">
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
<li class="nav-item">
<a class="nav-link" style="margin-left: 30px;" href="/">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" style="margin-left: 30px;" href="/profile">profile</a>
</li>
<li class="nav-item">
<a class="nav-link" style="margin-left: 30px;" href="#">Pricing</a>
</li>
</ul>
<ul class="navbar-nav ml-auto">
{% if user.is_authenticated %}
<div class="float-right">
<li class="nav-item active">
<a class="nav-link" href="#">New post</a>
</li>
</div>
<div class="float-right">
<li class="nav-item active">
<a class="nav-link" href="">{{ user.username }}</a>
</li>
</div>
<div class="float-right">
<li class="nav-item">
<a class="nav-link" href="/logout">Logout</a>
</li>
</div>
{% else %}
<div class="float-right">
<li class="nav-item">
<a class="nav-link" href="/login">Login</a>
</li>
</div>
<div class="float-right">
<li class="nav-item">
<a class="nav-link" href="/register">Register</a>
</li>
</div>
{% endif %}
</ul>
</div>
</div>
</nav>
{% block body %}
{% endblock %}
</body>
In your base.html file change
{{ created_post.user }}
with
{{ created_post.user }}
Because, you must pass id of post owner to your view. When you use only user, django detect authenticated user object.

Hide Elements within Jinja2 template? Any possible way to hide a button?

I am working on my web application using Python and Flask. I have got a navbar and some buttons on it and I would like to hide one of buttons when I am not on the index page. Is that possible? I would like the button "select brand" to be visible only on index.html page.
{% block navbar %}
<nav class="navbar navbar-expand-lg navbar-default fixed-top ">
<div class="container">
<div class="navbar-header">
<button button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<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" rel="home" href="{{ url_for('main.index') }}" title="Mobile phones and accessories">
<img style="max-width:40px; margin-top: -9px;"
src="http://www.logospng.com/images/38/devfest-2016-38885.png" >
</a>
</div>
<div id="navbar" class="collapse navbar-collapse navbar-responsive-collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
{% if current_user.is_authenticated and current_user.admin %}
<li>Add phone</li>
<li>Add brand</li>
{% endif %}
<li class="dropdown">
Select brand <span class="caret"></span>
<ul class="dropdown-menu">
{% for brand in brands %}
<li class="list-group-item">
{{ brand }}
{% endfor %}
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if current_user.is_authenticated %}
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<span class="glyphicon glyphicon-user"> </span> {{ current_user.username }}
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="{{ url_for('auth.logout') }}" >Logout</a></li>
</ul>
</li>
{% else %}
<li><a class="nav-link" href="{{ url_for('auth.login') }}" >Login</a></li>
<li><a class="nav-link" href="{{ url_for('auth.register') }}" >Register</a></li>
{% endif %}
</ul>
<form class="navbar-form navbar-right" method='POST' action="{{ url_for('phones.search') }}">
<div class="form-group">
<input class="search-query form-control" placeholder="Search..." aria-label="Search" type="text" name="search">
</div>
</form>
</div>
</div>
</nav>
{% endblock %}
Create a new variable within your index route and pass that variable into the render_template method of said route. The presence of this variable will determine if the <button> or link within your <nav> should be rendered or not. Since the <nav> will be shared across all other layouts, its HTML code should be put within your base layout, or the layout which all other views are inheriting from.
Something along the lines of:
index route:
#app.route("/")
def index():
# isIndex is the variable we will use to determine
# whether or not to render your navigation link or button
return render_template('index.html', isIndex=True)
base layout file:
<div class="navbar-nav">
{% if isIndex %}
<a class="nav-item nav-link" href="">linkOnlyForIndexPage</a>
{% else %}
<a class="nav-item nav-link" href="">link1</a>
<a class="nav-item nav-link" href="">link2</a>
{% endif %}
</div>
This is exactly what you're already doing with {% if current_user.is_authenticated %} for your navigation links. The reason this works is because the index route is the only route which sets this variable, within your jinja2 templates, so all other routes which render corresponding views will default to false on this conditional check: {% if isIndex %}
Hopefully that helps!
I think this will work.
Set the following on your child pages:
{% set active_page = "index" %}
Then in your base template:
{% if active_page == "index" %}
... button html here
{% endif %}

Flask Signing In and signing out

I am have created a sign in and sign out functionality to my Flask website. However, I am trying to hide the sign out button(on my navbar) when I am not signed in and show the sign-out button when I signed in.
Here are my logout and login methods:
#app.route('/login', methods=['GET', 'POST'])
def login():
error = None
if request.method == 'POST':
if (request.form['username'] != 'admin') \
or request.form['password'] != 'admin':
error = 'Invalid Credentials. Please try again.'
else:
session['logged_in'] = True
flash('You were logged in.')
return redirect(url_for('availability'))
return render_template('login.html', error=error)
#app.route('/logout')
#login_required
def logout():
session.pop('logged_in', None)
flash('You were logged out.')
return redirect(url_for('welcome'))
Here is my navbar for my website:
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<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="/">Student Support</a>
</div>
<div id="navbar" class="navbar-collapse collapse ">
<ul class="nav navbar-nav">
<li>Home</li>
<li>About Us</li>
<li>FAQ'S</li>
<li class="active">Availability</li>
<li>Quiz</li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if 'session['logged_in'] == True %}
<li>Logout <span class="sr-only">(current)</span></li>
{% else %}
<li>Login <span class="sr-only">(current)</span></li>
{% endif %}
</ul>
</div>
<!--/.nav-collapse -->
</div>
<!--/.container-fluid -->
</nav>
As you can see I have tried to do an if statement so if 'session['logged_in'] == True % display the logout button but it ain't working.
There was a typo it should be:
<ul class="nav navbar-nav navbar-right">
{% if session['logged_in'] == True %}
<li>Logout <span class="sr-only">(current)</span></li>
{% else %}
<li>Login <span class="sr-only">(current)</span></li>
{% endif %}
</ul>

Categories

Resources