Django : cannot retrieve numbers of objects - python

I am working on a Django (v1.11.0) project and I have this model called Album which allows every user to add albums.
I wrote the following to display the number of authenticated user, however nothing showed
#login_required()
def user_account(request):
user = request.user
user_albums = Album.objects.filter(user=request.user)
nb_albums = 0
for i in user_albums:
nb_albums = nb_albums + 1
context = {
'nb_albums': nb_albums
}
return render(request, 'music/user_account.html', {'user': user}, context)
Here is the code in the HTML page:
<td>{{ request.user }}</td>
<td>{{ request.user.first_name }}</td>
<td>{{ request.user.last_name }}</td>
<td>{{ request.user.email }}</td>
<td>{{ nb_albums }}</td>

Change your code:
#login_required()
def user_account(request):
user_albums = Album.objects.filter(user=request.user)
nb_albums = user_albums.count()
return render(request, 'music/user_account.html', {'nb_albums': nb_albums})
and for your template:
<td>{{ user }}</td>
<td>{{ user.first_name }}</td>
<td>{{ user.last_name }}</td>
<td>{{ user.email }}</td>
<td>{{ nb_albums }}</td>

Related

How to delete table content from sqlite Django

I want to delete the data when pressing the trash bin button. I am able to submit, edit petty cash into the database. I am only left with deleting the data.
This is my views.py
def deleteclaims(request, id):
context = initialize_context(request)
user = context['user']
#get id of particular form.
claims = SaveClaimForm.objects.get(id=id)
if request.method == 'POST':
claims.name = request.POST['name']
claims.email = request.POST['email']
claims.claim = request.POST['claim']
claims.claimtype = request.POST.get('claimtype')
claims.description = request.POST['description']
claims.receipt = request.FILES['receipt']
claims.cheque = request.POST.get('Cheque')
claims.status = request.POST['status']
claims.delete()
claims.save()
return render(request, 'Login/existingclaims.html', {'claims':claims, 'user':user}, {'action' : 'Delete claims'})
In my html
<tr align="center">
<td>{{ claims.id }}</td>
<td>{{ claims.name }}</td>
<td>{{ claims.email }}</td>
<td>{{ claims.claim }}</td>
<td>{{ claims.claimtype }}</td>
<td>{{ claims.description }}</td>
<td> Click to View </td>
<td>{{ claims.cheque }}</td>
<td>{{ claims.status }}</td>
<td><i class="fas fa-pencil-alt"></i></td>
<td><i class="fas fa-trash"></i></td>
</tr>

How to compare values of two for loops and use if statement in django template?

This might be a confusing question.
I have three tables in sqllite: 1) Events 2) Delegates 3) EventDelegate
1st one stores all events, 2nd one stores all delegates, 3rd one contains the eventid and delegateid to show that the particular delegate is attending that particular event.
In my event details page i only want to show the delegates whose id are present in the event_delegate table along with that event id. Currently im using this code but not working
views.py
def event_det(request, eid):
data = Event.objects.filter(id=eid) //SELECTING ONLY THE CLICKED EVENT
data2 = Delegate.objects.all() // SELECTING ALL THE DELEGATES FROM DB
data3 = EventDelegate.objects.filter(event_id=eid) //SELECTING RECORDS FROM EVENT_DELEGATE WHERE eventid is eid
return render(request, 'event_details.html', {'event': data, 'delegates': data2, 'selectdelegates': data3})
template
<tbody>
{% for del in delegates %}
{% for sd in selectdelegates %}
{% if del.id == sd.delegate_id %}
<tr>
<td>{{ del.id }}</td>
<td>{{ del.first_name }} {{ del.last_name }}</td>
<td>{{ del.email }}</td>
<td>{{ del.phone }}</td>
<td>{{ del.company }}</td>
<td>{{ del.designation }}</td>
<td>View</td>
</tr>
{% endif %}
{% endfor %}
{% endfor %}
</tbody>
I can share more details if required...
If you have a relationship between event and event delegate like this:
class EventDelegate(models.Model):
event = models.ForeignKey(Event, on_delete=models.DO_NOTHING)
delegate = models.ForignKey(Delegate, on_delete=models.DO_NOTHING)
Then you can try like this:
def event_det(request, eid):
data = Event.objects.get(id=eid) //SELECTING ONLY THE CLICKED EVENT
return render(request, 'event_details.html', {'event': data})
# template
{% for e in event.eventdelegate_set.all %}
<tr>
<td>{{ e.delegate.id }}</td>
<td>{{ e.delegate.first_name }} {{ e.delegate.last_name }}</td>
<td>{{ e.delegate.email }}</td>
<td>{{ e.delegate.phone }}</td>
<td>{{ e.delegate.company }}</td>
<td>{{ e.delegate.designation }}</td>
<td>View</td>
</tr>
{% endfor %}
Alternative solution:
#view
def event_det(request, eid):
data = EventDelegate.objects.filter(id=eid) //SELECTING ONLY THE CLICKED EVENT
return render(request, 'event_details.html', {'event_delegates': data})
# template
{% for e in event_delegates %}
// rest of the code as above example
More information can be found in documentation.
If I understand right, EventDelegate models have ForeignKey to an Event and to a Delegate. So what you want is a queryset of EventDelegate objects that are linked to the event in question.
ed_qs = EventDelegate.objects.filter( event_id = event.id )
(maybe add .order_by( "delegate__lastname") for alpha ordering and .select_related()
pass this to your template, and
<tbody>
{% for ed in ed_qs %}
<tr>
{{ed.delegate.whatever}} ...
Alternatively you might use .annotate in the queryset to copy the desired fields of the linked delegate onto the returned objects. You'd then refer to the annotations, via your chosen annotation names such as {{ed.delegate_firstname}}.My guess is that this would be maximally efficient, if that matters.

How to pass certain key and value of a python dictionary to HTML script

I am using flask and in one endpoint I just pass the following dictionary to html file:
app = Flask(__name__)
#app.route("/home")
def home():
q = {"id":23,
"path": '/usr/test.py',
"mynum": 22}
return render_template("home.html", query=q)
in HTML file:
{% for value in query.values() %}
<td>{{ value }}</td>
{% endfor %}
But in this way I am passing all the key-value's but I need to pass certain key-values. More clear, I expect such a solution in HTML if exist:
<td>{{ query["path"] }}</td>
<td>{{ query["id"] }}</td>
<td>{{ query["mynum"] }}</td>
I also tried this:
<td>{{ query.path }}</td>
<td>{{ query.id }}</td>
<td>{{ query.mynum }}</td>
but prints query.path, query.id , query.mynum rather than values
Printing dictionary specific key's value in Jinja2 template without loop
If you want to print specific key of a dictionary, you may use .get() method.
app.py:
from flask import Flask, render_template
app = Flask(__name__)
#app.route("/home")
def home():
q = {"id":23,"path": '/usr/test.py',"mynum": 22}
return render_template("home.html", query=q)
home.html:
<table>
<tr>
<th>ID</th>
<th>Path</th>
<th>Number</th>
</tr>
<tr>
<td>{{ query.get("id") }}</td>
<td>{{ query.get("path") }}</td>
<td>{{ query.get("mynum") }}</td>
</tr>
</table>
Output:
If the key is not found in the dictionary it will print None as value. You may also pass default value as second parameter of the get method.
E.g.:
{{ query.get("arsho", "Value not found") }}
It looks like the issue you are dealing with is that the order of the key/values in the dictionary is not the same order that you would like to display. Instead of hard-coding the <td> elements, you can create a list of the keys in the order you want them to appear and pass that to the template.
import jinja2
query = {"id":23,
"path": '/usr/test.py',
"mynum": 22}
ordered_keys = ('path', 'id', 'mynum')
h = '''<table><tr>
{% for k in ordered_keys -%}
<td>{{ query.get(k, '') }}</td>
{% endfor -%}
</tr></table>
'''
t = jinja2.Template(h)
print(
t.render(query=query, ordered_keys=ordered_keys)
)
# prints:
<table><tr>
<td>/usr/test.py</td>
<td>23</td>
<td>22</td>
</tr></table>

Cannot get HTML to display SQLite3 data with python & flask

I'm having an issue getting an HTML page to display my SQLite3 data using Python & Flask. I found a question on here and used the same code, plus different variations to no success. There are no error messages and the HTML page loads, however there is no data present. This is the code I am using to get the data;
#app.route("/viewpackages", methods=['GET'])
def viewpackages():
con = sqlite3.connect('utpg.db')
db = con.cursor()
user_id = session.get('id')
getpackages = db.execute("SELECT pck_id, client_id, date, price, privatelesson,"
"shortgamelesson, playinglesson, notes FROM packages WHERE client_id = ?;", (user_id, ))
return render_template("view_packages.html", items=getpackages.fetchall())
this is the code I attempting to use to display the data;
<table>
{% for item in items %}
<tr>
<td>{{column1}}</td>
<td>{{column2}}</td>
<td>{{column3}}</td>
<td>{{column4}}</td>
<td>{{column5}}</td>
<td>{{column6}}</td>
<td>{{column7}}</td>
<td>{{column8}}</td>
</tr>
{% endfor %}
</table>
I tried changing 'column' to the actual db column name, with the same issue. I tried calling SELECT * instead of each individual column, same issue. If I run this code in python;
con = sqlite3.connect('utpg.db')
db = con.cursor()
user_id = session.get('id')
getpackages = db.execute("SELECT pck_id, client_id, date, price, privatelesson, shortgamelesson, playinglesson, notes FROM packages WHERE client_id = ?;", (user_id, ))
packages = getpackages.fetchall()
for row in packages:
print(row)
It returns the desired results. So I am thinking there is an issue with the HTML somewhere but I cannot figure it out.
Please try the following code and let me know if it works for you:
<table>
{% for item in items %}
<tr>
<td>{{ item[0] }}</td>
<td>{{ item[1] }}</td>
<td>{{ item[2] }}</td>
<td>{{ item[3] }}</td>
<td>{{ item[4] }}</td>
<td>{{ item[5] }}</td>
<td>{{ item[6] }}</td>
<td>{{ item[7] }}</td>
</tr>
{% endfor %}
</table>
Test with the following code:
app.py
from flask import Flask, render_template
import sqlite3
app = Flask(__name__)
app.secret_key = 'development key'
#app.route('/users')
def get_users():
con = sqlite3.connect('mydb.db')
db = con.cursor()
db.execute('insert into user values ("Aaa", "AAA")')
db.execute('insert into user values ("Bbb", "BBB")')
res = db.execute('select * from user')
return render_template('users.html', users=res.fetchall())
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
templates/users.html
<html !DOCTYPE>
<head>
<title>SQLite</title>
</head>
<body>
<table>
{% for user in users %}
<tr>
<td>{{ user[0] }}</td>
<td>{{ user[1] }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
Here is what I had to do.. For anyone else having this issue, I'm not sure why but Jinja did not want to let me access by index so I did..
#app.route("/viewpackages", methods=['GET'])
def viewpackages():
con = sqlite3.connect('utpg.db')
con.row_factory = sqlite3.Row
db = con.cursor()
user_id = session.get('id')
getpackages = db.execute("SELECT pck_id, client_id, date, price, privatelesson,"
"shortgamelesson, playinglesson, notes FROM packages WHERE client_id = ?;", (user_id, ))
return render_template("view_packages.html", items=getpackages.fetchall())
and change the HTML to..
<table>
{% for col in items %}
<tr>
<td>{{ col['pck_id'] }}</td>
<td>{{ col['client_id'] }}</td>
<td>{{ col['date'] }}</td>
<td>{{ col['price'] }}</td>
<td>{{ col['privatelesson'] }}</td>
<td>{{ col['shortgamelesson'] }}</td>
<td>{{ col['playinglesson'] }}</td>
<td>{{ col['notes'] }}</td>
</tr>
{% endfor %}
</table>
All working now, thank for pointing me in the right direction!

uniqe and repeated values in HTML table using Python/Django

I need to build two 3x3 tables with numbers from 1 to 9. One table should have unique values.
I'm only able to get first table workin with {{ random_number }} and can't figure out what's wrong with the other one {{unique_random_number}}. I'm getting THIS.
Here's my code:
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', 'devtask1.views.index'),
url(r'^$', 'devtask1.views.index2'),
)
views.py
from django.shortcuts import render_to_response
from random import randint
def n():
return randint(1,9)
def index(request):
return render_to_response('index.html', {'random_number': n})
def un():
for i in range(1,10):
return i
def index2(request):
return render_to_response('index.html', {'unique_random_number': un})
index.html
<table>
<tr>
<td>{{ random_number }}</td>
<td>{{ random_number }}</td>
<td>{{ random_number }}</td>
</tr>
<tr>
<td>{{ random_number }}</td>
<td>{{ random_number }}</td>
<td>{{ random_number }}</td>
</tr>
<tr>
<td>{{ random_number }}</td>
<td>{{ random_number }}</td>
<td>{{ random_number }}</td>
</tr>
</table>
<table>
<tr>
<td>{{ unique_random_number }}</td>
<td>{{ unique_random_number }}</td>
<td>{{ unique_random_number }}</td>
</tr>
<tr>
<td>{{ unique_random_number }}</td>
<td>{{ unique_random_number }}</td>
<td>{{ unique_random_number }}</td>
</tr>
<tr>
<td>{{ unique_random_number }}</td>
<td>{{ unique_random_number }}</td>
<td>{{ unique_random_number }}</td>
</tr>
</table>
Why not pass unique random number by building an array shuffling it and passing it through the context.
import random
def un():
unums = []
for i in range(1,10):
unums.append(i)
random.shuffle(unums)
return unums
then in your html call the index, unique_random_number[0] through unique_random_number[9] they'll always be different because of the shuffle but you'll avoid the repeats.
Also, using django that table can be accomplished with a for loop much cleaner.

Categories