Django/Bootstrap 4: How to align elements inside of multiple parent divs - python

So I am developing a website and for the life of me I can't figure out how to align the description, price, stock and add cart button in multiple versions of the same <div>. I know it is to do with the size of the image I am using but I'm not sure how to fix this.
Here is a diagram of how I want it to look:
But when I apply a 'h-100' class to the card <div> this is what happens:
I want the images to keep their positions but for the descriptions, add cart button and price/stock to all be horizontally aligned, as well as the height of the overall cards to be the same.
Here is my Django template code:
{% extends 'base.html' %}
{% block content %}
<div class="container-fluid">
<div class="jumbotron">
<h2>Welcome to MyTea</h4>
<p>Here we have teas of all varieties from all around the globe</p>
</div>
<div class="row">
<div class="col-sm-3">
<h4>Categories</h4>
<ul class="list-group">
All Categories
{% for c in countcat %}
<a href="{{ c.get_absolute_url }}" class="list-group-item catheight">{{c.name}}
<span class="badge badge-light">{{c.num_products}}</span>
</a>
{% endfor %}
</ul>
</div>
<div class="col-sm-9">
{% for product in products %}
{% if forloop.first %}<div class="row">{% endif %}
<div class="col-sm-6">
<div class="card border-primary mt-3 h-100">
<div class="card-header"><h3>{{product.name}}</h3></div>
<div class="card-body">
{% if product.image %}
<div class="h">
<img src="{{product.image.url}}" class="img-fluid">
</div>
{% endif %}
<p class="bg-light font-weight-light ">{{product.description}}</p>
{% if product.stock > 0 %}
<a href="{% url 'add_cart' product.id %}" type="button" class="btn btn-primary btn-sm mb-2">
<p class="m-0">Add to cart</p>
</a>
{% else %}
<a href="#" type="button "class="btn btn-danger btn-sm mb-2">
<p class="m-0">Out of stock</p>
</a>
{% endif %}
<div class="card-footer">
<p>Price: €{{product.price}}</p>
<p>Stock left: {{product.stock}}</p>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock content %}
Thanks for any help

The code can be corrected with a simple re-alignment of the content inside .card and correctly closing </div> statements.
Remove {% if forloop.first %}<div class="row">{% endif %} statement and place <div class="row"> above the for loop.
Add to cart and Out of stock buttons should be placed inside .card-footer and .card-body should be closed appropriately. This will leave the image and description within .card-body
Make sure h-100 class is added to `.card'.
Might I suggest adding end of div comments to all the div statements. The code is readable better in this way and helps in mitigating missing or misplaced </div> statements.
{% extends 'base.html' %}
{% block content %}
<div class="container-fluid">
<div class="jumbotron">
<h2>Welcome to MyTea</h4>
<p>Here we have teas of all varieties from all around the globe</p>
</div>
<!-- .jumbotron -->
<div class="row">
<div class="col-sm-3">
<h4>Categories</h4>
<ul class="list-group">
All Categories
{% for c in countcat %}
<a href="{{ c.get_absolute_url }}" class="list-group-item catheight">{{c.name}}
<span class="badge badge-light">{{c.num_products}}</span>
</a>
{% endfor %}
</ul>
</div>
<!-- .col-sm-3 -->
<div class="col-sm-9">
<div class="row">
{% for product in products %}
<div class="col-sm-6">
<div class="card border-primary mt-3 h-100">
<div class="card-header">
<h3>{{product.name}}</h3>
</div>
<!-- .card-header -->
<div class="card-body">
{% if product.image %}
<div class="h">
<img src="{{product.image.url}}" class="img-fluid">
</div>
<!-- .h -->
{% endif %}
<p class="bg-light font-weight-light ">{{product.description}}</p>
</div>
<!-- .card-body -->
<div class="card-footer">
{% if product.stock > 0 %}
<a href="{% url 'add_cart' product.id %}" type="button" class="btn btn-primary btn-sm mb-2">
<p class="m-0">Add to cart</p>
</a>
{% else %}
<a href="#" type="button " class="btn btn-danger btn-sm mb-2">
<p class="m-0">Out of stock</p>
</a>
{% endif %}
<p>Price: €{{product.price}}</p>
<p>Stock left: {{product.stock}}</p>
</div>
<!-- .card-footer -->
</div>
<!-- .card -->
</div>
<!-- . col-sm-6 -->
{% endfor %}
</div>
<!-- .row -->
</div>
<!-- .col-sm-9 -->
</div>
<!-- .row -->
</div>
<!-- .container-fluid -->
{% endblock content %}

Related

Django: Form submit button not loading blog post {{ post.slug }} value in second form

My Django template renders the post.slug value in the first 'edit' form button correctly but on the modal pop up for the 'delete' it does not.
This was working a week or so ago. The 'Edit' button works perfectly, yet with almost identical code, under a Bootstrap modal (for confirmation of the post deletion) the 'Delete' button does not load the value="{{ post.slug }}"
my template:
{% extends "base.html" %}
{% block content %}
<div class="post-opinion">
<h3>{{ user }}'s Posts</h3>
</div>
<div class="container-fluid">
<div class="row">
<!-- Blog Entries Column -->
<div class="col-12 mt-3 left">
<div class="row">
{% for post in post_list %}
<div class="col-md-4">
<div class="card mb-4">
<div class="card-body">
<div class="image-container">
{% if "placeholder" in post.featured_image.url %}
<img class="card-img-top"
src="https://codeinstitute.s3.amazonaws.com/fullstack/blog/default.jpg">
{% else %}
<img class="card-img-top" src=" {{ post.featured_image.url }}">
{% endif %}
<div class="image-flash">
<p class="author">Author: {{ post.author }}</p>
</div>
</div>
<a href="{% url 'post_detail' post.slug %}" class="post-link">
<h2 class="card-title">{{ post.title }}</h2>
<p class="card-text">{{ post.excerpt }}</p>
</a>
<hr />
<p class="card-text text-muted h6">{{ post.created_on}} <i class="far fa-heart"></i>
{{ post.number_of_likes }}</p>
<div>
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-primary mt-3" value="{{ post.slug }}" name="edit">Edit</button>
<button type="button" class="btn btn-danger mt-3" data-toggle="modal" data-target="#delete-confirmation">
Delete
</button>
</form>
</div>
</div>
</div>
</div>
{% if forloop.counter|divisibleby:3 %}
</div>
<div class="row">
{% endif %}
{% endfor %}
</div>
</div>
</div>
{% if is_paginated %}
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li>« PREV </li>
{% endif %}
{% if page_obj.has_next %}
<li> NEXT »</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
<div class="modal fade" id="delete-confirmation" tabindex="-1" role="dialog" aria-labelledby="deleteConfirmationModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Are you sure you want to delete this post?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form method="post" class="d-inline">
{% csrf_token %}
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-danger" value="{{ post.slug }}"
name="delete">Delete</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

reduce line of code while fetching data from object to object?

I am creating a printing ordering service website in Django and I am stuck on the order page.
I have three tables named "product" ,"size", and "sizeProductMap" table.
views.py
products = Product.objects.get(prod_ID=id)
print(products.prod_Name)
sizesmap = SizeProductMapping.objects.filter(prod_id=id)
sizeslist = []
for data in sizesmap:
sizes = data.size_id
sizeslist.append(sizes.prod_size) # Here I am getting all the sizes I needed.
print(sizes.prod_size)
return render(request, "GalaxyOffset/product.html", {'products': products, 'sizeslist': sizeslist})
product.html
{% extends 'GalaxyOffset\basic.html' %}
{% block title%}Products{% endblock %}
{% block body%}
<div class="card my-2 mx-0 auto">
<div class="mx-4 my-2">
<h1>{{ products.prod_Name }}</h1>
</div>
<div class="row">
<div class="col-3">
<img class="border border-secondary my-4 mx-4" height="200"
src="{{products.prod_img.url}}"
width="200"/>
</div>
<div class="col-8 my-4">
<p> {{products.prod_Desc}}</p>
</div>
<div class="dropdown-divider"></div>
</div>
</div>
<div class="row">
<div class="col-4">
<div class="card mx-2 my-2 border border-secondary">
<div class="mx-2 mt-4">
{% for category in categories %}
<a id="{{ category.prod_ID }}" class="dropdown-item" href="{% url 'product' category.prod_ID%}">
{{ category.prod_ID }}. {{ category.prod_Name }}</a>
<div class="dropdown-divider"></div>
{% endfor %}
</div>
</div>
</div>
<div class="col-8">
<div class="card mx-2 my-2">
<div class="my-2">
<!-- How can I reduce Number of Line of code here. -->
{% for s in sizeslist %}
<input type="radio" name="sizes">{{s}}
</br>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}
Can you help me here to reduce the Numer of Lines in my views.py for fetching sizes and displaying in product.html?
You can use a list comprehension here.
sizesmap = SizeProductMapping.objects.filter(prod_id=id)
sizeslist = [data.size_id.prod_size for data in sizesmap]
or use .values()
Ex:
sizeslist = SizeProductMapping.objects.filter(prod_id=id).values('size_id__prod_size')

How do I use variables as selectors in HMTL/ Bootstrap4?

I'm trying to make a for loop to build an accordion in Bootstrap, but every time I click the button to expand/ collapse a card, every card expands/ collapses. I think this is due to a shared id across all cards, so I want to use the post title as the id selector for each card. Here is the code I currently have:
{% for post in blog_posts %}
<div id="accordion">
<div class="card">
<h3 class="card-header" id="header">
<button class="btn btn-info" data-toggle="collapse"
data-target="#body" aria-expanded="false"
aria-controls="post: ">
{{ post.title }}
<small><p>Posted by {{ post.author }} on
{{ post.date_added|date:'D M d, Y H:i' }}</p></small>
</button>
</h3>
<div id="body" class="collapse show" aria-labelledby="header"
data-parent="#accordion">
<div class="card-body">
{{ post.text|linebreaks }}
<small>
<a class="text-dark" href="{% url 'blogs:edit_post' post.id %}">
edit post</a>
</small>
</div>
</div>
</div>
{% empty %}
<p>There are no posts to display.</p>
{% endfor %}
I've tried changing the h3 id to {{ post.title }}, but that doesn't seem to work. Any help is much appreciated.
Example code:
https://getbootstrap.com/docs/4.0/components/collapse/#accordion-example
You need the id's to be unique for each accordion section (otherwise they will all open at once), you could use the post.id for that.
{% if blog_posts %}
<div id="accordion">
{% for post in blog_posts %}
<div class="card">
<h3 class="card-header" id="header-{{post.id}}">
<button class="btn btn-info" data-toggle="collapse"
data-target="#post-{{post.id}}" aria-expanded="false"
aria-controls="post-{{post.id}}">
{{ post.title }}
<small><p>Posted by {{ post.author }} on
{{ post.date_added|date:'D M d, Y H:i' }}</p></small>
</button>
</h3>
<div id="post-{{post.id}}" class="collapse show" aria-labelledby="header-{{post.id}}"
data-parent="#accordion">
<div class="card-body">
{{ post.text|linebreaks }}
<small>
<a class="text-dark" href="{% url 'blogs:edit_post' post.id %}">
edit post</a>
</small>
</div>
</div>
{% endfor %}
</div>
{% else %}
<p>There are no posts to display.</p>
{% endif %}

What should I do to make my photos appear in Django only safari?

I made my macbook disk format.
After the format, I included my project.
However, photos are not displayed on the project page.
If I go to a specific product, (single page) this is a photo.
The logo is also visible.
Pictures are not displayed to me only collectively.
Safari didn't see 'css/mdb.min.css'
Maybe I don't have something installed?
Before, everything worked.
Here photo display
product.html
{% extends 'base.html' %}
{% load static %}
{% block title %} {{ product.name }} - PVB {% endblock %}
{% block content %}
<main class="mt-5 pt-4">
<div class="container dark-grey-text mt-5">
<!--Grid row-->
<div class="row wow fadeIn">
<!--Grid column-->
<div class="col-md-6 mb-4">
<img src="{{ product.photo.url }}" class="img-fluid" alt="">
</div>
<!--Grid column-->
<div class="col-md-6 mb-4">
<!--Content-->
<div class="p-4">
<div>
<h2>{{product.product_name}}</h2><hr>
<h5><p>Description</p></h5>
<p class="text-justify"><h6>{{product.description}}</h6></p>
<p class="text-justify"><h6>Weight: {{product.weight}}g</h6></p><hr>
</div>
</div>
</div>
</div>
<hr>
</div>
</main>
{% endblock %}
here no
products.html
{% extends 'base.html' %}
{% load static %}
{% block title %} Offer - PVB {% endblock %}
{% block content %}
<section id="marks">
<div class="container">
<header>
<h1>Our Offer</h1>
</header>
</div>
</section>
<!-- Offers -->
<section class="text-center mb-4 py-4">
<div class="container">
<div class="row">
{% if products %}
{% for product in products %}
<!--Grid column-->
<div class="col-lg-3 col-md-6 mb-4">
<div class="card">
<div class="view overlay">
<img src="{{ product.photo.url }}" class="card-img-top" alt="">
<a href="{% url 'product' product.id %}">
<div class="mask rgba-white-slight"></div>
</a>
</div>
<div class="card-body text-center">
<h6 class="grey-text">{{ product.category }}</h6>
<h5>
<strong>
{{ product.product_name }}
</strong>
</h5>
</div>
</div>
</div>
<!--Grid column-->
{% endfor %}
{% else %}
<div class="col-sm-12 sm-12">
<p>No Products Available</p>
</div>
{% endif %}
</div>
</div>
</section>
{% endblock %}
Check your media folder , May be its empty

how to use for loop with bootstrap carousel

I have figured out how to use bootstrap carousel but problem is I want to render my featured stories to be in the carousel.
currently I have a carousel that shows three slides, but what I'm trying to do is to have featured stories instead of the three slides.
<div class='carousel slide' id="myCarousel">
<ol class="carousel-indicators">
<li class="active" data-slide-to="0" data-target="#myCarousel"></li>
<li class="active" data-slide-to="1" data-target="#myCarousel"></li>
<li class="active" data-slide-to="2" data-target="#myCarousel"></li>
</ol>
<div class="carousel-inner">
<div class="item active" id="slide1">
<img src="http://i.imgur.com/SQ691ZO.jpg" >
<div class="carousel-caption">
<h4>hello</h4>
<p>hi you</p>
</div>
</div>
<div class="item" id="slide2">
<img src="http://i.imgur.com/zN4h51m.jpg" >
<div class="carousel-caption">
<h4>hello</h4>
<p>hi you</p>
</div>
</div>
<div class="item" id="slide3">
<img src="http://i.imgur.com/3ruWvoG.jpg">
<div class="carousel-caption">
<h4>hello</h4>
<p>hi you</p>
</div>
</div>
</div>
<a class="left carousel-control" data-slide="prev" href="#myCarousel"><span class="icon-prev"></span></a>
<a class="right carousel-control" data-slide="next" href="#myCarousel"><span class="icon-next"></span></a>
So this is what I tried that's not quite working.
I have
{% for a in featuredStory %}
{{a.title}}
{{a.sub}}
<img src='{{a.get_featuredImage_url}}' class="img-rounded" alt="Cinque Terre" width="330" height="236"/>
{% endfor %}
working fine, but problem is to incorporate these with carousel.
with one featured story it works but with more than one, I get one in the top one in the bottom.
Here;s what I tried
<div class="row">
<div class="col-sm-8">
{% for a in featuredStory %}
<div class='carousel slide' id="myCarousel">
<ol class="carousel-indicators">
<li class="active" data-slide-to="0" data-target="#myCarousel"></li>
<li class="active" data-slide-to="1" data-target="#myCarousel"></li>
<li class="active" data-slide-to="2" data-target="#myCarousel"></li>
</ol>
<div class="carousel-inner">
<div class="item active" id="slide1">
<img src='{{a.get_featuredImage_url}}' class="img-rounded" alt="Cinque Terre" width="330" height="236"/> <div class="carousel-caption">
<h4> {{a.title}}</h4>
<p> {{a.sub}}
</p>
</div>
</div>
</div>
<a class="left carousel-control" data-slide="prev" href="#myCarousel"><span class="icon-prev"></span></a>
<a class="right carousel-control" data-slide="next" href="#myCarousel"><span class="icon-next"></span></a>
{% endfor %}
</div>
</div>
You can use the for loop inside carousel-inner:
<div class="carousel-inner">
{% for a in featuredStory %}
<div class="item {% if forloop.counter == 1 %}active{% endif %}" id="slide{{ forloop.counter }}">
<img src="{{ a.get_featuredImage_url }}" >
<div class="carousel-caption">
<h4>{{ a.title }}</h4>
<p>{{ a.sub}}</p>
</div>
</div>
{% endfor %}
</div>
Make sure to activate the first item by checking the counter:
{% if forloop.counter == 1 %}active{% endif %}
If there are other information such as class, title etc. that also you can set in context on the featuredStory and then render it here same as title or url.
Create div[class=item] dynamically with for loop in next way:
{% for item in featuredStory %}
<div class="item" id="slide{{forloop.counter}}">
<img src="item.get_featuredImage_url">
<div class="carousel-caption">
<h4>{{ item.title }}</h4>
<p>{{ item.sub }}</p>
</div>
</div>
{% endfor %}
I used loop.index instead of forloop.counter
<div class="carousel-inner">
{% for item in sliders %}
<div class="carousel-item {% if loop.index == 1 %}active{% endif %}" id="slide{{ loop.index }}" >
<img class="d-block w-100" width="330" height="236" src="{{ url_for('static', filename='images/sliders/') }}{{ item.imagelocation }}" alt="{{item.filmtitle}}">
<div class="carousel-caption">
<h4>{{ item.filmtitle }}</h4>
</div>
</div>
{% endfor %}
</div>

Categories

Resources