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? - flask

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

Related

I am trying to print account ıd, account no, equity, no of share on my website. I want to use Alpaca for this

I am not sure whether I should use broker apı keys or trading apı keys. I tried both of them but none of them worked. I put two photos one of them is api.py and the other one is my home page. The code that is at below is in a template folder in home.html
{% block content %}
{% if user.is_authenticated %}
<div class="text-center" style="padding-top:100px">
<h3>Welcome <b>{{ user.get_username }}</b> to SINO</h3>
</div>
<div class="text-align:left">
<h3>You are connected with Alpaca :)</h3>
</div>
<div class="text-align:left">
<b>Account ID:</b> {{Alaccount.id}}
</div>
</div>
<div class="text-align:left">
<b>Account Number:</b> {{Alaccount.account_number}}
</div>
</div>
<div class="text-align:left">
<b>Equity:</b> {{Alaccount.equity}}
</div>
<div class="text-align:left">
<b>Number of shares:</b> {{alpaccount.position.qty}}
</div>
</div>
</div>
[enter image description here][1]{% else %}

Flask - Delete image from static (boostrap card)

I'm trying to create a functionnality where the user is able to upload and delete some images on the fly. The deleting part works but not completely... it successfully deletes an image from my static folder, but for some reason it only deletes the first image it finds, and not the one that linked to the bootrap card.
For some reason it is not properly identifying the correct value and I can't figure out why :
1. Flask
#app.route('/deleteImg', methods=['GET', 'POST'])
def deleteImg(row):
if request.method == 'POST':
image_to_del = request.values.get('image_to_del', None)
print(f'image_to_del:{image_to_del}')
os.remove(os.path.join(UPLOAD_FOLDER,image_to_del))
return redirect('/uploadimg')
return render_template('uploadimg.html')
2. HTML
<form action="{{url_for('deleteImg')}}" method="POST">
<div class="row">
{% for row in pics %}
<div class="col-md-3 mt-3">
<div class="card">
<img src="{{ url_for('static', filename='pics/'+row)}}" alt="{{row}}" class="card_img_top" height="200">
<input type="hidden" name="image_to_del" class="image_to_del" value="{{row}}">Filename : {{row}}</input>
<h5 class="text-cent" >Filename : {{row}}</h5>
</div>
<div class="card-footer text-center">
<input type="submit" value="Delete" class="btn btn-success" />
</div>
</div>
{% endfor %}
</div>
</form>
I found this solution for those who might be interested. This is based on the work of "Cairocoders" Flask delete image from db
1. FLASK
#app.route('/deletelogo/<string:get_ig>', methods=['GET', 'POST'])
def deletelogo(get_ig):
print(f'get_ig :{get_ig}')
os.remove(os.path.join(LOGO_FOLDER,get_ig))
return redirect('/logoimg')
2. HTML
<div class="row">
{% for row in pics %}
<div class="col-md-3 mt-3">
<div class="card">
<img src="{{ url_for('static', filename='logo/'+row)}}" alt="{{row}}" class="card_img_top" height="200">
<input type="hidden" name="image_to_del" class="image_to_del" value="{{row}}">Filename : {{row}}</input>
<h5 class="text-cent" >Filename : {{row}}</h5>
</div>
<div class="card-footer text-center">
<td><p><span class="glyphicon glyphicon-trash"></span></p></td>
</div>
</div>

How to send data from django template to view function via request?

Basically what I want to do is that whenever user hits "view" button in below code then I send a post/get request and send "sel" as data to a view function because I have to use "sel" in view function. How to do this through forms or ajax request or something else ?
search.html
{% for sel in selections %}
<div class="col-md-4">
<div class="card mb-4 shadow-sm">
<img src="../static/listhome/media/images/house2.jpg" width="100%" height="225" preserveAspectRatio="xMidYMid slice" focusable="false" role="img" ><rect width="100%" height="100%" fill="#55595c"/></svg>
<div class="card-body">
<h3>Price: </h3>
<p> {{sel.address}}<br>
Bedrooms: <br>
Baths: <br>
Square Feet: {{sel.approximate_square_footage}}
</p>
<div class="d-flex justify-content-between align-items-center">
<div class="btn-group">
## THIS IS BUTTON TO BE USE TO SEND DATA
<button type="submit" class="btn btn-sm btn-outline-secondary">View</button>
</div>
<small class="text-muted">Days listed: </small>
</div>
</div>
</div>
</div>
{% endfor %}
'Selections' is a list containing some elements from my database. It is the filtered result of my database passed to this template earlier through the following code:
views.py
def search(request):
value = request.POST.get('searchvalue')
selections = Listing.objects.filter(address__contains=value)
context={
'selections':selections,
'value':value,
}
return render(request, 'search.html',context)

Django: object attribute showing different values

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.

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