Display profile image in nav bar - html

I am building my own blog site.
I managed to have the users upload their own profile pic and have it displayed beside their post but now i want to have that same image be displayed in the navbar as a profile image but when i do it the same way i did it with the posts it doesnt work and looks like this.
For the posts i made a profile image model and accessed the variable from within the html file but the same method does not work for displaying it in the nav bar.
I am using python and django for backend.
This is my model code for the profile image:
from django.db import models
from django.contrib.auth.models import User
from PIL import Image
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"
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
This is how i reference it in my html file for displaying next to posts:
<img class="rounded-circle article-img" src="{{ post.author.profile.image.url }}" id="img">
When i use any other image(either from a url or a local file) it works perfectly but when I use that variable to call the image it doesn't work
It might be worth mentioning that the navbar and post sections are in different html files. it looks like the nav bar's html file does not have access to that variable?
What am I doing wrong?

Try this:
<img class="rounded-circle article-img" src="{{ request.user.profile.image.url }}" id="img">

Related

Django displaying a static image through a variable from models that is in a JSON object

I have been trying to display an image using Django in my HTML.
Normally do display a static file somebody would do:
<img src="{% static 'user_profile_pics/pfp_2.jpg' %}" >
This image static file has been stored in the variable picture in my models.py.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
picture = models.TextField(max_length=500)
The user selects the image they want to choose as their profile image. The views.py file is below with the profile definition having the request JSON dictionary with the variable picture being assigned to the model profile.picture.
#login_required
def profile(request):
profile = Profile.objects.get(user = request.user)
return render (request, "profile.html", {"userinfo": {'bio': profile.bio, 'picture': profile.picture}})
def register(request):
if request.method == 'POST':
first_name = request.POST['first_name']
last_name = request.POST['last_name']
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
confirm_password = request.POST['confirm_password']
bio = request.POST['bio']
picture = request.POST['picture']
if password==confirm_password:
if User.objects.filter(username=username).exists():
messages.info(request, 'Username is already taken')
return redirect(register)
elif User.objects.filter(email=email).exists():
messages.info(request, 'Email is already taken')
return redirect(register)
else:
user = User.objects.create_user(username=username, password=password, email=email, first_name=first_name, last_name=last_name)
user.save()
profile = Profile(bio=bio, picture=picture, user=user)
profile.save()
return redirect('login_user')
else:
messages.info(request, 'Both passwords are not matching')
return redirect(register)
else:
return render(request, 'registration.html')
Next up, displaying the bio and picture within the profile html works like this.
<div id = "userprofiletext">
{% if user.is_authenticated %}
<a class="text" >Your Description is: , {{bio}}</a>
<img src= {{userinfo.picture}} />
{% endif %}
</div>
Before implementing the JSON, the bio managed to display. I believe something must be done in the HTML to get it to display and need some help. The picture when displaying on my page does not register but when debugging it is clear that 'picture' is picture file link. The picture on the page never shows up.
I have tried to figure out displaying the bio and picture as they have been correctly passed into the models. There is a django load static line at the top of my HTML file page as well.
Edit:
Everything looks normal in this picture yet it is still not displaying?
The image
Put {{userinfo.picture}} in double quotes
<img src="{{userinfo.picture}}" />

How can I display PIL image to html with render_template flask?

I tried to display my edited image with PIL package, when I tried to make it to display on the html <img src=''></img> it doesn't appear anything, but I see the file name on inspect elements was <img src="<_io.BytesIO object at 0x000001EDA8F76E00>">. How do I make the edited image display properly?
app.py
#app.route("/api/games/shipper/image/", methods=["GET"])
def games_shipper():
... # My stuff up here
image_io = BytesIO()
img.save(image_io, "PNG")
image_io.seek(0)
return render_template('image.html', image_data=image_io)
image.html
... // My stuff up here
<body>
<center>
<image src="{{ image_data }}"></image>
</center>
</body>
You can read the data from the buffer with the getvalue() function and then convert it. The base64 encoded data can then be passed to the src parameter as a data url.
from base64 import b64encode
#app.route("/api/games/shipper/image/", methods=["GET"])
def games_shipper():
... # My stuff up here
image_io = BytesIO()
img.save(image_io, 'PNG')
dataurl = 'data:image/png;base64,' + b64encode(image_io.getvalue()).decode('ascii')
return render_template('image.html', image_data=dataurl)
If you pass the image as a dataurl, there is no way to shrink the string. However, there is the possibility of serving the file as pure image data. You can use send_file in another endpoint for this. You serve the page (template) in one endpoint and the image file in a second.
from flask import send_file
#app.route('/')
def index():
return render_template('index.html')
#app.route('/image')
def game_shipper():
# ...
image_io = io.BytesIO()
img.save(image_io, format='PNG')
image_io.seek(0)
return send_file(
image_io,
as_attachment=False,
mimetype='image/png'
)
<body>
<center>
<img src="{{ url_for('game_shipper') }}" />
</center>
</body>
You'll need to encode your image in Base64 to display it in the img tag directly, see e.g. How to display Base64 images in HTML
The traditional way to display images in Flask templates is to save the image in Flask's static folder and link to it in your template like so
<body>
<center>
<image src="/static/{{image_name}}.png"></image>
</center>
</body>

Simple Background Image, Django unable to find image

Just wanting to make a simple multiple page website and I cant seem to get the background image to show on local host, Django just keeps saying Image not found. Can anyone help with this?? I want to drop vue in and do some fun stuff, but If I can't even get the images to show its going to be no fun at all.
The HTML File.
<body>
<section id="hero" class="d-flex align-items-center">
<div id="bg">
<div class="bg">
<img
src="{% static "media/ocean.jpg" %}"
class="bg1"
alt=""
/>
My View File
from django.shortcuts import render
# Create your views here.
def homepage(request):
return render(request, '/Users/mossboss/Dev/SimpleWS/apps/core/templates/core/base.html')
My Settings
STATIC_URL = '/static/'
STATICFILES_DIRS = [
BASE_DIR / 'static'
]
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

How to change image path dynamically with Flask

Hi is there a way to dynamically load different images whenever I get into my flask app?
I've got 10 images each is named 'accueil_X' with X is 0,1,2,...
app.py
#app.route('/', methods=("POST", "GET"))
def home():
random = randrange(10)
random_pix = 'accueil_'+str(random)+'.png'
HTML
<img src="{{url_for('static', filename='+{{ random_pix }}+')}}" width=100%, alt="">
Jinja seems to load an image named +{{ random_pix }}+: How can I fix this ? thank you
so you want to load a random image with each refresh of the home page:
#app.route('/', methods=("POST", "GET"))
def home():
random = randrange(10)
random_pix = 'accueil_'+str(random)+'.png'
[..]
# i added this missing line to get code more clear
return render_template('home.html', random_pix=random_pix)
Jinja seems to load an image named +{{ random_pix }}+: How can I fix this ?
it's simple, just remove the {{ }} surrounding the variable random_pix
<img src="{{ url_for('static', filename='\'' + random_pix + '\'') }}" width=100%, alt="">
jinja2 uses {{ .. }} to evaluate any valid expression
refer to this doc
You could do this with a context processor which is the equivelant of Django's "template tag".
This can be used to pass a number of variables to all templates, or pass a function which can then be called in all templates.
First import the required modules, and initialise the app:
from flask import Flask, url_for, render_template
from random import randrange
app = Flask(__name__)
Then define a context processor:
#app.context_processor
def utility_processor():
def random_image():
number = randrange(10)
f = 'accueil_' + str(number) + '.png'
return url_for('static', filename=f)
return dict(rand_im=random_image)
Notice you've passed the random_image function which can then be called in the template as rand_im. Instead of putting the call to url_for in the template, you've done this in Python.
So you could render this with the following in any template:
<img src="{{ rand_im() }}" width="100%" />

Django 1.11 How to display template variable from within HTML saved in model for CMS Site

Within a template, I need to render a {{ variable }} from HTML content saved in a model instance.
Below are the stripped down parts of the code.
page.html
{% load static %}
<html>
<head>
<styles, links, etc.>
<title>{{ object.title }}</title>
</head>
<body>
<div>{{ object.html_content }}</div>
</body>
</html>
Model
class Page(models.Model):
title = models.CharField(max_length=30)
html_content = models.TextField()
GlobalMixin
# Used site wide for Global information.
class GlobalMixin(object):
def get_context_data(self, *args, **kwargs):
context = super(GlobalMixin, self).get_context_data(*args, **kwargs)
context['variable'] = "A Global piece of information"
return context
View
from .mixins import GlobalMixin
from .models import Page
PageView(GlobalMixin, generic.DetailView):
model = Page
template_name = "my_app/page.html"
def get_context_data(self, *args, **kwargs):
context = super(PageView, self).get_context_data(*args, **kwargs)
return context
Admin & HTML Content Field
I then enter admin, add new Page, enter my HTML content into html_content Field "Html Content" as per the following example.
<p>This is {{ variable }} that I need to display within my rendered page!</p>
Then SAVE.
BROWSER RESULTS
This is {{ variable }} that I need to display within my loaded page!
I know there is Django Flat Pages, but it doesn't look like it works for me as I require Global variables in my templates that flat pages doesn't offer.
The template is being rendered directly with the models content without looking at it.
I think I need to process the html_content field in the view and then add the required context variables to the context returned or save a temporary template file, append the html_content into the file, then render it.
How do I do make this work?
Is there a Django packaged interface that I can use to process the template from within my view?
I worked it out. Here's the code if anyone else comes across this or has a better way, please share.
Change View type to TemplateView, use slug in url to get model instance, use django.template.engines to convert the string to a template object then render the template object and return it in the context.
page.html
{% load static %}
<html>
<head>
<styles, links, etc.>
<title>{{ object.title }}</title>
</head>
<body>
<!-- <div>{{ object.html_content }}</div> -->
<div>{{ html_content }}</div>
</body>
</html>
views.py
from django.views.generic.base import TemplateView
from .mixins import GlobalMixin
from .models import Page
# NEW
from django.shortcuts import get_object_or_404
from django.template import engines
PageView(GlobalMixin, TemplateView): # generic.DetailView
# model = Page
template_name = "my_app/page.html"
def get_context_data(self, *args, **kwargs):
context = super(PageView, self).get_context_data(*args, **kwargs)
# NEW
context['object'] = get_object_or_404(Page, slug=self.kwargs['slug'])
t = engines['django'].from_string(context['object'].html_content)
context['html_content'] = t.render(context=context, request=None)
return context
I thought you could use custom filter like below.
file path
yourapp/templatetags/__init__.py
yourapp/templatetags/filters.py
filters.py
from django import template
import re
register = template.Library()
#register.filter(name="change_global_variable")
def change_global_variable(value):
return re.sub(r'\{\{(.*)\}\}', 'A global piece', value)
template
{% load static %}
{% load filters %} //filters.py//
<html>
<head>
<styles, links, etc.>
<title>{{ object.title }}</title>
</head>
<body>
<div>{{ object.html_content | change_global_variable}}</div>
</body>
</html>