How to create a dynamic bootstrap carousel, using flask/python? - python

For context:
I'm building a social network. Just like with Facebook, each profile has a tab titled "images", which is a collection of thumbnails from the profile owner's posts.
My goal:
Just like with Facebook, I'd like the user navigating the page to be able to click on any thumbnail image, launching a bootstrap carousel and displaying that specific image in a much larger view. The user could then use the carousel-control class to scroll through the profile owner's other images.
Current situation:
The thumbnails display, you can click on any thumbnail and launch the carousel, but all of the profile owner's images appear stacked, as if they're all active.
I'm using a jinja2 for loop and a url_for statement to access the images. I also use a loop counter within an if statement to make it so only one image is active, but its obviously not working :(
It was this 4 year old stackoverflow post that I used to attempt solving this problem to begin with.
When using the carousel with a few images added statically it works properly, but I need it to be dynamic for obvious reasons.
I'm unsure how to go about showing just the specific image that was clicked on, and having the ability to scroll through the others.
Any help will be greatly appreciated!
Here is my HTML
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
{% for post in user.posts %}
{% if post.post_img != None %}
<div class="container">
<div class="item {% if loop.counter == 1 %} active {% endif %}" id="slide{{ loop.counter }}">
<img src="{{ url_for('static', filename='post_pics/' + post.post_img) }}">
</div>
<a class="carousel-control-prev" href="#pageCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon bg-primary" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#pageCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon bg-primary" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
{% endif %}
{% endfor %}
</div>
</div>

You can move the a tags outside the inner-carousel div, maybe like below ( its untested)
If you look at the documentaion, the a tags have to be outside.
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
{% for post in user.posts %}
{% if post.post_img != None %}
<div class="carousel-item {% if loop.index == 1 %} active {% endif %}" id="slide{{ loop.index }}">
<img src="{{ url_for('static', filename='post_pics/' + post.post_img) }}">
</div>
{% endif %}
{% endfor %}
</div>
<a class="carousel-control-prev" href="#pageCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon bg-primary" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#pageCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon bg-primary" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>

Related

How to insert images from render( , , context) in Django?

guys! New in Django so maybe it's a silly question. I have a .json file that keeps information about shop's clothes including "img". The goal is to otput all the information about products in a single "for loop". So I've written such lines
{% for product in products %}
<div class="col-lg-4 col-md-6 mb-4">
<div class="card h-100">
<a href="#">
<img class="card-img-top"
src="{% static '{{ product.img }}' %}" !!! problem is here
alt="">
</a>
<div class="card-body">
<h4 class="card-title">
{{ product.name }}
</h4>
<h5>{{ product.price }}</h5>
<p class="card-text"> {{ product.description }}</p>
</div>
<div class="card-footer text-center">
<button type="button" class="btn btn-outline-success">Отправить в корзину</button>
</div>
</div>
</div>
{% endfor %}
Everything works fine except the line concerns an image. In devtools I get the next path "/static/%7B%7B%20product.img%20%7D%7D". But in the .json file it looks like "img": "vendor/img/products/Brown-sports-oversized-top-ASOS-DESIGN.png". I am totally confused about that situation and definitely in a bind. I appreciate any help
work with:
<img src="{{ product.img.url }}">
if the image is effective (product.img is not None), and you added the media urls to the urls.py, then it will determine the URL where to fetch the product image.
Note that in production, Django does not serve media files, so in that case you will need to configure the webserver (Apache, Nginx, etc.) to serve media files for you.

Using For loop and If condition in Django to display Images in Bootstrap Carousel

I haven been looking everywhere for a case similar to this, but haven't found anything that could solve my problem. I want to display an image from a model in my html inside a for loop, which has an if condition. This is my models.py:
from django.db import models
# Create your models here.
class CarouselItem(models.Model):
carousel_picture = models.ImageField(upload_to='carousel_images/', null=True, blank=True)
views.py:
from django.shortcuts import render
from .models import CarouselItem
# Create your views here.
def index(request):
carousel_items = CarouselItem.objects.all()
context = {
'carousel_items': carousel_items
}
return render(request, "home/index.html", context=context)
and my html:
{% if carousel_items %}
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
{% for item in carousel_items %}
{% if forloop.first %}
<div class="carousel-item active">
<img src="{% item.carousel_picture.url %}" class="d-block w-100" alt="...">
</div>
{% else %}
<div class="carousel-item">
<img src="{% item.carousel_picture.url %}" class="d-block w-100" alt="...">
</div>
{% endif %}
{% endfor %}
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
{% else %}
<h3>We are sorry, there are currently no Images to display</h3>
{% endif %}
When I want to access the page associated with the html I get this error message:
Invalid block tag on line 86: 'item.carousel_picture.url', expected 'elif', 'else' or 'endif'. Did you forget to register or load this tag?
I feel like I am making a mistake somewhere else, but I can't figure out what it is. I am using Bootstrap 4.5.3 and Django 3.1.5
All of the other html files in this project have no issues with displaying images using for loops.
Instead of using:
{% item.carousel_picture.url %}
which is for templates logic, use:
{{ item.carousel_picture.url }}
which uses the value.

Problem iterating through MongoDB data using Flask & Jinja2

brand new to Flask/Python and i'm trying to iterate through a list of data from MongoDB using Flask. The data is grabbed with no issues but the result i get is all of the database entries stuffed into one div. Below i've provided some screenshots to further explain the problem.
The 2 MongoDB Entries:
The idea is to have 2 separate cards displaying the 2 entries. The card will display the name_moving, once clicked, the rest of the info will appear in a modal.
HTML Template Code:
<div id="modal1" class="modal request_info_wrap">
{% for user_details in user_details: %}
<div class="modal-content request_info_card">
<h4 class="request_name_header">{{ user_details.user_name }} {{ user_details.user_lname }}</h4>
<p class="request_info"><span class="request_title">Request
Address:</span><br>{{ user_details.user_street }}<br>{{ user_details.user_postcode }}</p><br>
<p class="request_info"><span class="request_title">Contact
Number:</span><br>{{ user_details.user_contact }}</p><br>
<p class="request_info"><span class="request_title">Requested
Date:</span><br>{{ user_details.user_date }}</p><br>
<div class="deep_clean_section">
<p class="request_info" style="color: #000;"><span class="request_title">Deep Clean
for:</span><br>{{ user_details.carpet_clean }}<br>{{ user_details.floor_steam }}<br>
{{ user_details.white_goods }}<br>{{ user_details.window_clean }}
</p>
</div><br>
<hr style="margin: 0;">
<p class="request_info"><span class="request_title">Customer
Message:</span><br>{{ user_details.user_message }}</p>
</div>
<div class="modal-footer job_card_btn_wrap">
<a href="#" class="modal-close replyto_btn">Reply to
{{ user_details.user_name }}</a>
</div>
{% endfor %}
</div>
</div>
The issue i'm having is that both entries show within the same div (shown below) whereas im trying to get each MondoDB entry to show individually when clicked.
Python/Flask Code:
#app.route("/deep_clean_info", methods=["GET", "POST"])
def deep_clean_info():
if request.method == "POST":
user_details = {
"user_name": request.form.get("user_name"),
"user_lname": request.form.get("user_lname"),
"user_contact": request.form.get("user_contact"),
"user_street": request.form.get("user_street"),
"user_postcode": request.form.get("user_postcode"),
"user_message": request.form.get("user_message"),
"user_date": request.form.get("user_date"),
"carpet_clean": request.form.get("carpet_clean"),
"floor_steam": request.form.get("floor_steam"),
"white_goods": request.form.get("white_goods"),
"window_clean": request.form.get("window_clean"),
}
mongo.db.user_details.insert_one(user_details)
flash("Request sent to cleaner")
return redirect(url_for("deep_clean_info"))
details = mongo.db.user_details.find().sort("user_details", 1)
return render_template("deep_clean_details.html", user_details=details)
I do think the issue is with my jinja2 for loop in my template but any help would be greatly appreciated, also if any additional information is needed i'll be more than happy to provide. Thanks!
EDIT
HTML Template that seemed to iterate fine, although i dont want to use this style to display the data.
<ul class="collapsible popout pending_jobs">
{% for user_details in user_details %}
<li>
<div class="collapsible-header request_item_header">
<i class="fas fa-comment-dots"></i>
{{ user_details.user_name }} {{ user_details.user_lname }}
</div>
<div class="collapsible-body request_info">
<div class="row">
<span class="row info_headers">Address:<br>
<span class="light_text info_text" id="customer_address">
{{ user_details.user_street }}</span>
</span><br>
<span class="info_headers">Contact Number:<br>
<span class="light_text info_text" id="customer_contact">{{ user_details.user_contact }}</span>
</span><br>
</div>
<span class="info_headers row customer_request_style">Customer Request:<br>
<span class="light_text italic_text" id="customer_request">{{ user_details.user_message }}</span>
</span><br>
<span class="info_headers">Cleaning Date:<br>
<span class="light_text italic_text" id="customer_request">{{ user_details.user_date }}</span>
</span><br>
<a href="{{ url_for('cleaner_chat') }}"><button class="respond_to_user">Respond to
{{ user_details.user_name }}?</button></a>
</div>
</li>
{% endfor %}
</ul>

How to use Django for loop twice on the same data

I'm attempting to use a for loop to iterate over the same data twice in the same Django template. However the second for loop only returns the first object in the database.
Basically I have an image of each job in the database on the homepage and when clicked on it should display a more detailed description of that job. All the jobs from the database display fine on the homepage but they all display the description of the first job when clicked on.
I think it's something to do with only being able to use an iterator once but I can't figure out what the solution is.
model.py
from django.db import models
class Job(models.Model):
title = models.CharField(max_length=50, default="Example Work")
image = models.ImageField(upload_to='images/')
summary = models.TextField()
views.py
from django.shortcuts import render
from .models import Job
def get_index(request):
jobs = Job.objects
return render(request, 'index.html', {'jobs': jobs})
index.html
{% for job in jobs.all %}
<div class="col-md-6 col-lg-4">
<a class="portfolio-item d-block mx-auto" href="#portfolio-modal">
<div class="portfolio-item-caption d-flex position-absolute h-100 w-100">
<div class="portfolio-item-caption-content my-auto w-100 text-center text-white">
<i class="fas fa-search-plus fa-3x"></i>
</div>
</div>
<img class="img-fluid" src="{{ job.image.url }}" alt="">
</a>
<h3 class="text-center text-secondary">{{ job.title }}</h3>
</div>
{% endfor %}
<!-- Portfolio Modal -->
{% for job in jobs.all %}
<div class="portfolio-modal mfp-hide" id="portfolio-modal">
<div class="portfolio-modal-dialog bg-white">
<a class="close-button d-none d-md-block portfolio-modal-dismiss" href="#">
<i class="fa fa-3x fa-times"></i>
</a>
<div class="container text-center">
<div class="row">
<div class="col-lg-8 mx-auto">
<h2 class="text-secondary text-uppercase mb-0">{{ job.title }}</h2>
<hr class="star-dark mb-5">
<img class="img-fluid mb-5" src="{{ job.image.url }}" alt="Image of website">
<p class="mb-5">{{ job.summary }}</p>
<a class="btn btn-primary btn-lg rounded-pill portfolio-modal-dismiss" href="#">
<i class="fa fa-close"></i>Close Project</a>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
Just for context, I've ripped out a lot of the html code from index.html because that all works fine and it probably isn't relevant. I've tried it in within one loop which doesn't work either. The description opens up within a new window on the same page. I've tried anything I can think of but not getting anywhere with it. Still getting to grips with Django and Python. Any help appreciated.
This isn't anything to do with Django outputting the same data for each iteration. If you check the generated HTML via View Source in your browser, you'll definitely see the correct data.
The problem is with your HTML itself. You cannot have multiple elements with the same HTML id attribute; but you are using id="portfolio-modal" for each one. When your JS tries to pop up the modal, it will only ever find the first instance of this ID.
You need to use a different ID in each iteration - perhaps by appending a unique element, eg the Job pk - and/or use a class to trigger your modal.

Content from two columns doesn't show as expected Django and Bootstrap 4

I'm currently building a blog+portfolio with Django and Bootstrap 4.
The problem is when I try to show two columns, Articles next to my Profile. Both columns are in an HTML table, but for some reason, they do not show correctly.
For example:
How it looks like using HTML,CSS, and Bootstrap
Here is how it looks when I insert everything on my Base_layout.html
How it looks like when it is inserted in my django Base_layout.html
Here is my Base_layout, which has the code inside the table to show the articles of the blog ({% load bootstrap4 %} {% load static from staticfiles %} are included in the top of the document):
<div class="container">
<div class="row">
<!-- Blog Entries Column -->
<div class="col-md-8">
<div class="card mb-4" class="article-detail">
{% block content %}
{% endblock %}
</div>
</div>
<!-- Pagination -->
<ul class="pagination justify-content-center mb-4">
<li class="page-item">
<a class="page-link" href="#">← Older</a>
</li>
<li class="page-item disabled">
<a class="page-link" href="#">Newer →</a>
</li>
</ul>
</div>
<!-- Sidebar Widgets Column -->
<div class="col-md-4">
<div class="card" style="width: 18rem;">
<img src="{% static 'profile.jpg' %}" class="rounded-circle card-img-top" alt="">
<div class="card-body">
<h5 class="card-title">Leandro Fraisinet</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
More
</div>
</div>
</div>
</div>
</div>
Here is the code that is to be shown by Blog Entries Column
Article_list html:
{% extends 'base_layout.html' %}
{% load bootstrap4 %}
{% block content %}
<h1> </h1>
{% for article in articles %}
<div class="card-body" class="article">
<img class="card-img-top" src="{{ article.thumb.url}}" alt="Main post image">
<h2 class="card-title">{{article.title}}</h2>
<p class="card-text">{{article.snippet}}</p>
</div>
<div class="card-footer text-muted">
<p>{{article.date}}</p>
</div>
<h1> </h1>
{% endfor%}
{% endblock %}
I think that my main conflict is in Blog Entries Column but I do not know how to solve this.
Please any extra code that could be useful to solve this let me know.
Django version, 1.11 Phyton version 2.7, Bootstrap version 4.
You sidebar column is outside the row
<div class="row">
<!-- Blog Entries Column -->
<div class="col-md-8">
</div>
<!-- Pagination -->
<ul class="pagination justify-content-center mb-4">
</ul>
</div>
<!-- Sidebar Widgets Column -->
<div class="col-md-4">
</div>
try to put it inside:
<div class="container">
<div class="row">
<!-- Blog Entries Column -->
<div class="col-md-8"></div>
<!-- Sidebar Widgets Column -->
<div class="col-md-4"></div>
</div>
<!-- Pagination -->
<ul class="pagination justify-content-center mb-4"></ul>
</div>

Categories