Flask - simple delete of database entry - missing positional argument - flask

I’m new to flask, I am just trying to get a simple delete request to remove a database entry.
html table
...
{% for l in logbook %}
<tr>
<td>{{ l.TO_UTC }}</td>
<td>{{ l.LDG_UTC }}</td>
<td>{{ l.dep_airport }}</td>
<td>{{ l.arr_airport }}</td>
<td>Delete {{ l.id }}</td>
</tr>
{% endfor %}
...
the id_del refers to the delete app route:
#app.route('/logbook/delete')
def logbookdelete(id_del):
delete = Logbook.query.filter_by(id=id_del).first()
db.session.delete(delete)
db.session.commit()
return redirect(url_for('logbook'))
Current error: TypeError: logbookdelete() missing 1 required positional argument: 'id_del'
How do I get the {{ l.id }} to be used as the id_del in the app route?
Many thanks

Add <id_del> in route.
#app.route('/logbook/delete/<id_del>')
def logbookdelete(id_del):
delete = Logbook.query.filter_by(id=id_del).first()
db.session.delete(delete)
db.session.commit()
return redirect(url_for('logbook'))

Related

Django looping through items not showing

Hi I am looping through items being passed through the context but nothing is showing.
This is the data I have:
{"error":[],"result":{"USDT":"60000.00000000","CHZ":"13773.0349000000","ZRX":"0.0000000000","ZUSD":"67787.8285","DOT":"0.0000000000","COMP":"0.0000034600","ENJ":"257.6815000000","ADA":"2473.80445621","XXDG":"17006.92601155","ALGO":"32063.69514500","XXBT":"0.0000012880","SUSHI":"172.4585500000","SOL":"1133.3543869800","DASH":"0.5104491200","LINK":"144.2407000000","ATOM":"151.26763831","XXLM":"6926.27220000","XXRP":"0.00000000","XETH":"14.5877343640","TRX":"923.80015900","KNC":"0.0000000000","BAL":"0.0000000000","XLTC":"11.4923900000","KSM":"24.7142610000","SC":"0.0000000200","OCEAN":"652.6077000000","MATIC":"1838.9295772000","AAVE":"83.6218990800","ZGBP":"30622.0790","XZEC":"0.0000073100"}}
It is passed in my context like this:
def kraken(request):
""" A view to return kraken page """
context = {
'api_reply': api_reply,
}
return render(request, 'home/kraken.html', context)
And inside my template I have this:
{% for k, v in api_reply.items %}
<tr>
<td>{{ k }}</td>
<td>{{ v }}</td>
</tr>
{% endfor %}
I have no errors showing but it is not displaying, any help would be great thank you.
The items are stored in the result subelement, you thus should enumerate over api_reply.result.items, not api_reply.items:
{% for k, v in api_reply.result.items %}
<tr>
<td>{{ k }}</td>
<td>{{ v }}</td>
</tr>
{% endfor %}
Furthermore you need to convert the JSON blob into Python objects, for example with:
import json
def kraken(request):
""" A view to return kraken page """
context = {
'api_reply': json.loads(api_reply),
}
return render(request, 'home/kraken.html', context)

Django - How to retrieve columns in template automatically from a query in views.py?

There is a module with 30 columns.
I query this table in the views.py to get the last record (last row).
To get the data in template (index.html), I have to write each column and in front of it, its value. I have to do it 30 times!
is there anything like {{form}} to get all the columns and their value automatically or at least by using {% for ... %}?
in views.py
def articlesindex(request):
data = Articles.objects.all().last()
return render(request, 'Articles\index.html', {'articles':data})
in index.html
{{ articles }} (does not work)
{{ articles.a_table }} (does not work)
{% for k,v in articles %} (does not work)
<tr>
<td>{{ k }}</td>
<td>{{ v }}</td>
</tr>
{% endfor %}
That is because last() return a single object in a queryset (see the documentation here). So, as it is a single object you will have a single row. You can render the object as follow:
<tr>
<td>{{ articles.attr_1 }}</td>
<td>{{ articles.attr_2 }}</td>
...
<td>{{ articles.attr_n }}</td>
</tr>
The attribute one by one

Run python in a html template while iterating though a list

def ViewCharges(request):
account = get_object_or_404(StripeAccount, team_members=request.user)
payment_requests = PaymentRequest.objects.filter(company=account).order_by('-created')
return render(request, 'dashboard/charges.html',{'payment_requests':payment_requests})
This is how my template looks after doing
{% for request in payment_requests %}
<tr>
<td>{{ request.name }}</td>
<td>{{ request.email }}</td>
<td>{{ request.amount }}</td>
<td>{{ request.paid }}</td>
<td><a href="/dashboard/charges/{{ request.pk }}" class='btn btn-dark btn-sm'>Manage</a></td>
</tr>
{% endfor %}
And in my models, I store the paid field in pence (e.g 100 = £1), this is for stripe. And I can properly format it by doing
real_amount = "{:.2f}".format(amount / 100)
this works fine until I need to do it in a for loop in html, is there a way I can do this in the html doc
<tr>
<td>Bob</td>
<td>Bob#example.com</td>
<td>£20</td>
<td>Yes</td>
<td><a href="/dashboard/charges/3523" class='btn btn-dark btn-sm'>Manage</a></td>
</tr>
The rest is fine I just need some help with that formatting, does anybody have any suggestions?
Create a property on your models to calculate real_amount. Then you can access this property in your HTML template or anywhere else just like any other field attribute of your model.
Example:
class MyModel(...):
...
#property
def real_amount(self):
return "{:.2f}".format(self.amount / 100)
Then in your templates:
{{ request.real_amount }}

How to put "python functions" into HTML files in a Django Project

Working in a Django Project. I have an index.html file with a variable called "todas_academias", which is a list of models classes that I've created.
Directory: FKSC/ac_filiados/templates/ac_filiados/index.html
{% for academia in ordenar(todas_academias) %}
<td>{{ academia.nome_academia }}</td>
<td>{{ academia.estado }}</td>
<td>{{ academia.cidade }}</td>
<td>{{ academia.professor }}</td>
<td>{{ academia.num_alvara }}</td>
{% endfor %}
And I created a function called "ordenar" in a python file in another directory.
Directory: FKSC/ac_filiados/functions.py
You DON'T NEED to understand what this function does.
def ordenar(todas_academias):
lista = []
for academia in todas_academias:
lista = lista + [academia.num_alvara]
nova_list = lista.sort()
nova_lista_academias = []
for reg in nova_list:
for academia in todas_academias:
if reg == academia.num_alvara:
nova_lista_academias = nova_lista_academias + [academia]
return nova_lista_academias
Now, I just want to use the "ordenar()" function in the index.html file, as I tried to use, but it didn't work.
1) Do I need to import the "ordenar" function before using it? If so, How do I import it?
2) Should I've placed the "ordenar" function in views.py?
3) Or, is there a specific way of using this kind of functions in HTML files?
You shouldn't call a function from the template. I would pass what ordenar returns via context dictionary to the view like so:
views.py
def ordenar(todas_academias):
lista = []
for academia in todas_academias:
lista = lista + [academia.num_alvara]
nova_list = lista.sort()
nova_lista_academias = []
for reg in nova_list:
for academia in todas_academias:
if reg == academia.num_alvara:
nova_lista_academias = nova_lista_academias + [academia]
return nova_lista_academias
def some_view(request):
...
YOUR OTHER CODE
...
return render(request, 'yourtemplate.html', {ordenar: 'ordenar'})
Then in your template you would keep the same code more or less:
{% for academia in ordenar %}
<td>{{ academia.nome_academia }}</td>
<td>{{ academia.estado }}</td>
<td>{{ academia.cidade }}</td>
<td>{{ academia.professor }}</td>
<td>{{ academia.num_alvara }}</td>
{% endfor %}
You can add result of your function inside the context of your view or create django template tag inclusion-tags doc and example: custom-inclusion-tags

Django Creating Using Context In Rendered View

I am rendering a view to an html template. I do not get any errors but the data does does not loop on the page.
I had this working but once i started using the template I have had problems. So I know it works I am just not understanding using context to render the response.
I am making a request to an api then assigning the response to a variable. Then I am creating the context based on the variable of the response. At this point I understand I should be able to access the data with the context variable. What is the proper way of assigning a response to a a context and using the data in a template tag.
In the view
def github(request):
jsonList = []
req = requests.get('https://api.github.com/users/DrkSephy')
str_response = req.content.decode('utf-8')
jsonList.append(json.loads(str_response))
parsedData = []
userData = {}
for data in jsonList:
userData['name'] = data['name']
userData['blog'] = data['blog']
userData['email'] = data['email']
userData['public_gists'] = data['public_gists']
userData['public_repos'] = data['public_repos']
userData['avatar_url'] = data['avatar_url']
userData['followers'] = data['followers']
userData['following'] = data['following']
moviesList = parsedData.append(userData)
context = {'moviesList': moviesList}
return render(request, 'serviceapp/github.html', context)
In the html file
{% for movie in moviesList %}
<tr>
<td>{{ movie.name }}</td>
<td>{{ movie.blog }}</td>
<td>{{ movie.avatar_url }}</td>
<td>{{ movie.public_repos }}</td>
<td>{{ movie.public_gists }}</td>
<td>{{ movie.email }}</td>
<td>{{ movie.followers }}</td>
<td>{{ movie.following }}</td>
</tr>
{% endfor %}
{% for moviesList in moviesList %}
^both the variables here are identical - you already use moviesList for the whole list, so you cant use it again for the variable inside loop. Use something like this:
{% for item in moviesList %}
{{ item.name }}
...
{% endfor %}
edit:
ok, so I looked at your code again. Have you tried to print the variables in your view if they are filled correctly? Because they are not. Look at this line:
moviesList = parsedData.append(userData)
^ what you do here is you assign the result of parsedData.append() (which is None, because append is in-place modification) to the moviesList variable, which is then None.