Django: object attribute showing different values - django

So this looks like a lot of code, but I only really care about the two lines where I put arrows.
This code snippet is from a template (html) file.
solutions_newest is an array full of "solution" objects. A "solution" has an attribute called "id". {{ solution.id }} accesses the id of a solution.
The two lines where I put arrows are in the same for loop, so it should be accessing the same solution at a given time. However, when I display {{ solution.id }} in both these lines, the first line displays the id of the selected puzzle, and the second line always displays the id of the first puzzle of the "solutions" array.
How can this be?
I suspect that I am not fully understanding how Bootstrap modals work, but to be honest I have no idea why {{ solution.id }} is showing different ids in the two lines with arrows.
{% for solution in solutions_newest %}
<div class="card bg-light">
<div class="card-header subtitle">
<div class="triple-left">{{ solution.datetime }} by
{{ solution.user.username }}
</div>
{% if user == solution.user or user.profile.teacher %}
<div class="triple-right">
edit
--------------> <a class="text-danger" href="#" data-toggle="modal" data-target="#deleteSolutionNewest">{{ solution.id }}: delete</a>
<!-- Modal -->
<div class="modal fade" id="deleteSolutionNewest" tabindex="-1" role="dialog" aria-labelledby="deleteSolutionNewestLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="deleteSolutionNewestLabel">Are you sure?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
Once you delete a solution, you lose it forever.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
--------------> {{ solution.id }}: Delete
</div>
</div>
</div>
</div>
</div>
{% endif %}
<div class="triple-center points">
<a class="block-link" href="{% url 'solution' puzzleID=solution.puzzle.id solutionID=solution.id %}">⇑</a>
{{ solution.points }}
<a class="block-link" href="{% url 'solution' puzzleID=solution.puzzle.id solutionID=solution.id %}">⇓</a>
</div>
</div>
<a class="block-link" href="{% url 'solution' puzzleID=solution.puzzle.id solutionID=solution.id %}">
<div class="card-body">
<h5 class="card-title">{{ solution.title }}</h5>
<p class="card-text">{{ solution.content | markdown | safe }}</p>
</div>
</a>
</div>
<br>
{% endfor %}
Any help is appreciated. Thank you!

In HTML Element IDs SHOULD be unique within the entire document. I suspect the problem is caused by having multiple objects with the same id, because having a tag with id="deleteSolutionNewestLabel" in your for loop will result in several tags with the id deleteSolutionNewestLabel.
The html 5.1 spec says getElementById must return the first element with the given ID, so the behavior you see is not unexpected. Most (if not all) browsers have and still do select the first element with a given ID, when calling getElementById. Most libraries that find elements by ID inherit this behavior. Check "Can multiple different HTML elements have the same ID if they're different elements?"
Try to replace all instances of id="deleteSolutionNewestLabel" with id="deleteSolutionNewestLabel-{{ forloop.counter }}" and let me know if it fixes the problem.

Related

data id iteration django

I really do not know how to iterate through my loop to display individual items. I have tried to
rearrange the loop but has worked. The data id id="portfolioModal" is what I want to also iterate for individual items.
{% for subjects in object %}
<div class="portfolio-modal modal fade" id="portfolioModal" tabindex="-1" role="dialog" aria-labelledby="portfolioModal1Label" aria-hidden="true">
<div class="modal-dialog modal-xl" role="document">
<div class="modal-content">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">
<i class="fas fa-times"></i>
</span>
</button>
<div class="modal-body text-center">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-8">
<!-- Portfolio Modal - Title -->
<h2 class="portfolio-modal-title text-success text-uppercase mb-0">{{subjects.title}}</h2>
<!-- Icon Divider -->
<div class="divider-custom">
<div class="divider-custom-line"></div>
<div class="divider-custom-icon">
<i class="fas fa-star"></i>
</div>
<div class="divider-custom-line"></div>
</div>
<!-- Portfolio Modal - Image -->
<img class="img-fluid rounded-circle mb-5" src=" {{subjects.img.url}}" alt="">
<!-- Portfolio Modal - Text -->
<p>{{subjects.desc}}</p>
<button class="btn btn-danger" href="#" data-dismiss="modal">
<i class="fas fa-times fa-fw"></i>
Close Window
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
If you want to iterate just numbers in the loop, you can use the {{ forloop.counter }}, like this:
{% for subjects in object %}
<div class="portfolio-modal modal fade" id="portfolioModal-{{ forloop.counter }}" tabindex="-1" role="dialog" aria-labelledby="portfolioModal1Label" aria-hidden="true">
...
{% endfor %}
In the for loop inside your template code, ever single object of your the context "object" variable is named "subjects", like you know. So, If you want iterate your div id using a object attribute (suppose object.id), just call it by {{ subjects.id }}:
{% for subjects in object %}
<div class="portfolio-modal modal fade" id="portfolioModal-{{ subjects.id }}" tabindex="-1" role="dialog" aria-labelledby="portfolioModal1Label" aria-hidden="true">
...
{% endfor %}
When this page is rendered,this will print a simple id=portfolioModal-1, id=portfolioModal-2, id=portfolioModal-3... where numbers are the objects ids

How can I pass an image ID from the view into my routes.py, when the images are displayed in the view via a for loop?

I'm building a simple portfolio website where the owner will be able to manage a gallery page, Adding, Editing and Removing posts. I am printing the images from the DB using a for loop and need a way in order to get either the name of the image or the ID of the image and send the value back to the route in order to delete the row from the DB. Any suggestion would be much appreciated.
Additional information:
Using Flask w/ SQLalchemy & WTforms
Sample of how I'm displaying the images and accompanying data:
{% for image in Posts | reverse %}
<div class="row pt-3">
<div class="col">
<img class="img-fluid rounded" src="static/gallery_images/{{image.image }}" alt="">
</div>
</div>
<div class="row pt-4">
<div class="col">
<h3 style="display: inline">{{image.title}}</h3>
<p class="font-italic text-muted" style="display: inline">
{% if image.sold_flag %}
- Sold
{% else %}
- Available
{% endif %}
</p>
<p class="text-muted">{{image.date_posted.strftime('%d/%m/%Y')}}</p>
</div>
</div>
<div class="row">
<div class="col">
<p class="font-weight-normal">{{ image.description }}</p>
</div>
</div>
<div class="row">
{% if current_user.is_authenticated %}
<div class="col text-left">
<button type="button" class="btn btn-dark">Edit</button>
<button type="button" class="btn btn-danger">Delete</button>
</div>
{% endif %}
</div>
<hr class="border">
{% endfor %}
There are multiple ways to store the id and use it for a route call. Using purely what you have shared, you can add a call to the button to the respective endpoints:
Assuming you have a method images.delete(id) to delete images and that you want to keep with the button tag on your code:
<a href={{url_for('delete.edit', id=image.id)}}>
<button type="button" class="btn btn-dark">
Delete
</button>
</a>
However, I would really recommend for you to use a form to submit the delete, as opposed to a GET request generated above. This way you can have it secured with WTForm CSRF token.
Example:
HTML
<form action="{{url_for('delete.edit', id=image.id)}}" method="POST" role="form">
{{ form.hidden_tag() }}
</form>
Python
## Make sure to create the delete form
class DeleteImage(Form):
pass

Django Bootstrap Grid all content breaks onto new line

I am building a website using the Django framework where it will display a grid of places (3 per row) however the code below, every place ends up going onto a new line within the column.
<div class="site-container container-fluid">
<div class="row">
<div class="col-md-3 col-lg-2">
<div class="thumbnail">
<a href="{% url 'sites:details' site.id %}">
<img src="{{ site.site_picture}}" class="img-responsive">
</a>
<div class="caption">
<h2>{{ site.site_name }}</h2>
<h4>{{ site.site_street }}</h4>
<!-- View Details -->
View Details <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
</div>
</div>
</div>
</div>
</div>
In my browser I see the content I want however every site is on a new line in the column, whereas I would like it to be in a row of three and break onto a new line and then begin another row of three.
Screenshot
I think it is because you are executing all within the
<div class="col-md-3 col-lg-2">
If you inspect the browser do you see only one of these elements? If so then that would be your problem. What you want is something like,
<div class="site-container container-fluid">
<div class="row">
LOOP OUTSIDE OF HERE!!!!!!!! <---------------------
<div class="col-md-3 col-lg-2">
<div class="thumbnail">
<a href="{% url 'sites:details' site.id %}">
<img src="{{ site.site_picture}}" class="img-responsive">
</a>
<div class="caption">
<h2>{{ site.site_name }}</h2>
<h4>{{ site.site_street }}</h4>
<!-- View Details -->
View Details <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
</div>
</div>
</div>
That way you will get multiple columns each holding its own content.

include bootstrap modal template with template tags

I'm trying to create a bootstrap modal that can be included in my html files since I'm putting forms in modal and I don't want to create a new mdoal everytime.
It works fine, except for trying to include the form. Which is of course the important part. How could I include a template context variable inside a template tag?
modal_base
{% load crispy_forms_tags %}
<div id="{{ modal_form_id }}" class="modal fade" ariahidden="True">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<a class="close" data-dismiss="modal">X</a>
<h1 style="text-align:center;">
{{ modal_form_title }}
</h1>
</div>
<div class="modal-body">
<form method="{{modal_form_method|default:'POST'}}" action="{{modal_form_action}}">
{% csrf_token %}
{{ form|crispy }}
<input class="btn btn-primary" type="submit" value="Create"/>
</form>
</div>
<div class="modal-footer">
<a href="#" class="btn btn-danger" data-dismiss="modal">
Cancel
</a>
</div>
</div>
</div>
</div>
Example include in some html file:
{% include 'modal_form.html' with modal_form_id="new-category" modal_form_title="Create a New Category" modal_form_method="POST" modal_form_action="/home/" form={{category_form}} %}
form = {{category_form}} is the issue. Is there a way to get around this?
The modal renders fine, opens closes etc I just can't pass in the form
You're close! the only thing missing is that you don't need the curly braces to include it within the include tag
{% include 'modal_form.html' with modal_form_id="new-category" modal_form_title="Create a New Category" modal_form_method="POST" modal_form_action="/home/" form=category_form %}

bootstrap and django keep button and input on same line

I would like to be my select input and button on the same line.
This i can get to work, but my input is stretched to the col width and not the input width.
How can i achieve this?
my code so far:
<form action="{% url 'register_user' %}" method="post">
{% csrf_token %}
<div class="row">
{% for field in filter_form %}
<div class="col-md-9">
<div class="form-group">
{{ field|addcss:"form-control" }}
</div>
</div>
<div class="col-md-3">
<button type="submit" class="btn btn-primary btn-sm">Filter</button>
</div>
{% endfor %}
</div>
</form>
What am i missing?
Side note: is there some way to make my button a bit wider than the text in it?
First you need to understand what the following code does. It creates a column of width 9/12 the width of the page.
<div class="col-md-9">
You might wan to do the following.
<div class="col-md-9">
<div class="form-group">
{{ field|addcss:"form-control" }}
<button type="submit" class="btn btn-primary btn-sm">Filter</button>
</div>
</div>
Give explicit width to the button. Check online to give width inline