Want to display rating stars in django - python

I am in new in django and i have a model "album" which has 3 fileds title , genre and rating and i am displaying them i a table and i want to display the digit"0" as many time as album.rating and i am using for loop from 0 to album.rating but it is displaying only once i.e if the album.rating is 2 then "0" should display only 2 times but in my case it is displaying only 1 time .Please help me.Thanks in advance.
Here is the code of the html -
{% if albums %}
{% for album in albums %}
<tbody>
<tr>
<td>{{ album.album_title }}</td>
<td>{{ album.genre }}</td>
<!-- rating stars -->
<td>
{% for i in album.rating %}
<option value={{i}}>0</option>
{% endfor %}
</td>
<td>
Edit
</td>
<td>
</td>
</tr>
</tbody>
Here is the code of view.py
def index(request):
if not request.user.is_authenticated():
return render(request, 'music/login.html')
else:
albums = Album.objects.filter(user=request.user)
paginator = Paginator(albums, 2) # Show 25 contacts per
page = request.GET.get('page')
try:
albums = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
albums = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
albums = paginator.page(paginator.num_pages)
song_results = Song.objects.all()
query = request.GET.get("q")
if query:
albums = albums.filter(
Q(album_title__icontains=query) |
Q(artist__icontains=query)
).distinct()
song_results = song_results.filter(
Q(song_title__icontains=query)
).distinct()
return render(request, 'music/index.html', {
'albums': albums,
'songs': song_results,
})
else:
return render(request, 'music/index.html', {'albums': albums})

Since you could not get the way to implement, after explaining:
{% for i in album.rating %} is like {% for i in 2 %} in your case, which turns out that, for a single digit, it's going to loop once. use range filter or so on.
I can suggest the quickest way to get it implemented via the answer: Check this
{% if albums %}
{% for album in albums %}
<tbody>
<tr>
<td>{{ album.album_title }}</td>
<td>{{ album.genre }}</td>
<!-- rating stars -->
<td>
{% with ''|center:album.rating as range %}
{% for i in range %}
<option value={{i}}>0</option>
{% endfor %}
{% endfor %}
</td>
<td>Edit</td>
<td></td>
</tr>
</tbody>
{% endif %}
Humble opinion, please look into DJango template filters and try and check
this.
P.S: have not evaluated the solution

Related

Django-filter: count data

Does anybody knows how can I use count based on selected value using django_filters
Error
'UserFilter' object has no attribute 'count'
My Reference link
views.py
def search(request):
user_list = Person.objects.all()
user_filter = UserFilter(request.GET, queryset=user_list)
count = user_filter.count() #this will return an error
print(count)
return render(request, 'user_list.html', {'filter': user_filter})
filters.py
from django.contrib.auth.models import User
from .models import Person
import django_filters
class UserFilter(django_filters.FilterSet):
class Meta:
model = Person
fields = ['category', 'firstname', 'lastname' ]
user_list.html
{% extends 'base.html' %}
{% block content %}
<form method="get">
{{filter.form.as_p}}
<button type="submit" >Search</button>
</form>
<table class="table table-bordered">
<thead>
<tr>
<th>Firstname</th>
<th> Lastname</th>
<th>Caegory</th>
</tr>
</thead>
<tbody>
{% for user in filter.qs %}
<tr>
<td>{{ user.firstname }}</td>
<td>{{ user.lastname }}</td>
<td>{{ user.category }}</td>
</tr>
{% empty %}
<tr>
<td colspan="5">No data</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
I want to count all the list base from data I filtered
You'll want the count of the resulting queryset, which you can get from the filter's qs property (as you do in your template!).
Change
count = user_filter.count()
to
count = user_filter.qs.count()
You can work with the .qs attribute:
def search(request):
user_list = Person.objects.all()
user_filter = UserFilter(request.GET, queryset=user_list)
count = user_filter.qs.count()
return render(request, 'user_list.html', {'filter': user_filter})
.qs [GitHub] is a property that generates a QuerySet by filtering the original queryset by values in the fields of the FilterSet.

Django: retrieve table data in html page

I have a Django table with 3 fields.
I have a total of 4 entries and i want to visualize all of them inside a table which only displays 2 of these 3 fields.
How should i do that? i did manage to only display 1 row instead of 4, i'm struggling, someone could help?
This is the easy model to manage.
class Inc(models.Model):
id = models.AutoField(primary_key=True)
nr_sin = models.CharField(max_length=50, default=None)
nr_pol = models.CharField(max_length=50, default=None)
Have you already got the QuerySet being passed from your view to your templates?
Assuming you have, and it's in a variable called inc_list, then in your template you could do this to display the nr_sin and nr_pol fields:
{% if inc_list %}
<table>
<thead>
<tr>
<th>NR SIN</th>
<th>NR POL</th>
</tr>
</thead>
<tbody>
{% for inc in inc_list %}
<tr>
<td>{{ inc.nr_sin }}</td>
<td>{{ inc.nr_pol }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
In you view query your model to get all the entries you want to display in the table and pass them as a context variable to the templete. Later in the template you have to iterate over the list of elements and render one by one as follow:
# import your model
class SomeView(View):
def get(self, request):
elements = Inc.objects.all()
context = {'elements': elements}
return render(request, 'your_template.html', context)
render the table:
<table>
<thead>
<tr>
<th>ID</th>
<th>nr_sin</th>
</tr>
</thead>
<tbody>
{# you loop over the list and render one element at each iteration #}
{% for inc in elements %}
<tr>
<td>{{ inc.pk }}</td>
<td>{{ inc.nr_sin }}</td>
</tr>
{% endfor %}
</tbody>
</table>

Optimize code in Django - view ManyToMany as matrix

I'm trying to show user group permissions in Django and show them in a "Drupal" style like a matrix. It works, but it takes too long to make the query and paint it in the template. Is there some way to improve my code?
view img
up(accomplished),down(views and template.html)
views :
def GroupPermissionsView(request):
title = "Groups Permissions"
groups = Group.objects.all()
permissions = Permission.objects.all()
context = Context({
'title': title,
'groups': groups,
'permissions': permissions,
})
return render(
request,
'forms_permissions.html',
context
)
template:
<table class="table table-striped table-inverse table-responsive table-bordered">
<thead>
<tr>
<th>Permission</th>
{% for group in groups %}
<th>{{ group.name }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for permission in permissions %}
<tr>
<td><b>{{permission.name}}<b></td>
{% for group in groups %}
{% if permission in group.permissions.all %}
<td><input type="checkbox" name="" checked="checked"></input></td>
{% else %}
<td><input type="checkbox" ></input></td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
Your problem was that you run more than 4 * 200 queries, one query for every combination or rows and columns (permissions and groups). It is useful to get them all by one query. It is however not easy because the intermediate model of ManyToMany relationship between Permission and Group models is not explicit in django.contrib.auth.models. You can get that model by Model._meta API:
>>> GroupPermissions = Permission._meta.get_field('group').through
>>> GroupPermissions
<class 'django.contrib.auth.models.Group_permissions'>
>>> GroupPermissions._meta.db_table # the table that you use in the raw query
'auth_group_permissions'
Put it all together. Prefer a longer view and simple template:
update the view:
from collections import OrderedDict
GroupPermissions = Permission._meta.get_field('group').through
groups = Group.objects.all()
permissions = Permission.objects.all()
permission_group_set = set()
for x in GroupPermissions.objects.all():
permission_group_set.add((x.permission_id, x.group_id))
# row title and cells for every permission
permission_group_table = OrderedDict([
(permission, [(permission.id, group.id) in permission_group_set for group in groups])
for permission in permissions
])
context = Context({
'title': title,
'groups': groups,
'permission_group_table': permission_group_table,
})
update the template
{% for permission, cells in permission_group_table.items %}
<tr><td><b>{{permission.name}}<b></td>
{% for cell in cells %}
{% if cell %}
<td><input type="checkbox" name="" checked="checked"></input></td>
{% else %}
<td><input type="checkbox" ></input></td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}

Django web page- how to manipulate what information is displayed in a table

I have a Django project, and one of my views renders a page that displays a table with information about objects in the database. The objects displayed differ based on the criteria determined in the view.
The if statement used in the view to determine which page to render is:
if request.GET.get('stage') == 'pd':
print "request.GET.get('stage') == 'pd' "
print "render_to_string() called with parameter: costing/report2_ccis.html"
context['html'] = render_to_string('costing/report2_ccis.html', context)
context['active_tab'] = '4'
if(project.deposit_received == True):
print "costing/reports_post_deposit.html is the page being rendered (project.deposit_received = true)... "
context['post_deposit'] = True
print "context['post_deposit']: ", context['post_deposit']
return render(request, 'costing/reports_post_deposit.html', context)
elif(project.deposit_received == False):
print "costing/reports_pre_deposit.html is the page being rendered (project.deposit_received = False)..."
context['post_deposit'] = False
print "context['post_deposit']: ", context['post_deposit']
return render(request, 'costing/reports_pre_deposit.html', context)
else:
print "request.GET.get('stage') != 'pd' "
print "render_to_string() called with parameter: costing/report_ccis.html"
context['html'] = render_to_string('costing/report_ccis.html', context)
context['active_tab'] = '5'
if(project.deposit_received == True):
print "costing/reports_post_deposit.html is the page being rendered (project.deposit_received = true)..."
context['post_deposit'] = True
print "context['post_deposit']: ", context['post_deposit']
return render(request, 'costing/reports_post_deposit.html', context)
elif(project.deposit_received == False):
print "costing/reports_pre_deposit.html is the page being rendered (project.deposit_received = false)..."
context['post_deposit'] = False
print "context['post_deposit']: ", context['post_deposit']
return render(request, 'costing/reports_pre_deposit.html', context)
Both of the templates returned in the view extend another template called reports_tabbed.html, and the report_ccis.html & report2_ccis.html templates that are passed to the render_to_string view both extends another template called pdf2_base.html.
The table that's displaying the information on the webpage (whichever one is passed to render_to_string- report_ccis.html or report2_ccis.html) is defined in pdf2_base.html with:
<table class="pdf-report left">
{% for payment_details in payments_details %}
{% if forloop.first %}
<thead>
<tr>
{% for detail in payment_details %}
<th>{{ detail.0 }}</th>
{% endfor %}
<th></th>
</tr>
</thead>
{% endif %}
<tbody>
{% if 0 %}
<tr class="end-table-section"></tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
{% endif %}
<tr {% if forloop.last %}class="end-table-section last-row"{% endif %}>
{% for detail in payment_details %}
<td {% if detail.0 == 'Gross payment (£)' %}class="payment-{{detail.2}}"{% endif %}>
{% if detail.1 and detail.0 != 'Date paid' and detail.0 != 'Date' %}
{% if detail.0 == 'VAT (£)' or detail.0 == 'Scheduled payment (£)' or detail.0 == 'Gross payment (£)' %}
{{ detail.1|money }}
{% else %}
{{ detail.1 }}
{% endif %}
{% elif detail.1 %}
{{ detail.1|date:'d-M' }}
{% endif %}
</td>
{% endfor %}
<td></td>
</tr>
{% if 0 %}
<tr class="end-table-section"></tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
{% endif %}
{% endfor %}
<tr class="end-table-section">
<td>Gross payment now due:</td>
<td>{{gross_payment_due|money:'£'}}</td>
<td>Current contract sum</td>
<td>Exc VAT {{ latest_total_exc|money:'£' }}</td>
<td></td>
<td>Bank</td>
<td>Handelsbanken</td>
</tr>
<tr>
<td></td>
<td></td>
<td>Total payments made</td>
<td>Exc VAT {{total_paid_exc|money:'£'}}</td>
<td></td>
<td> acc</td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
<td>Outstanding contract sum</td>
<td>Exc VAT {{outstanding_exc|money:'£'}}</td>
<td>Inc VAT {{outstanding_inc|money:'£'}}</td>
<td>Sort Code</td>
<td></td>
</tr>
<tr class="last-row">
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td colspan="2">Please ensure address is put as reference</td>
</tr>
</tbody>
</table>
What I want to do, is change this table in the template when it is displayed by the if(project.deposit_received == False) conditions in the view, so that one of the columns in the table ('Latest Sum') is not displayed in the table... But given that the table is generated & populated using Django for loops, as it changes dynamically based on the information retrieved from the database, I'm not sure how to do this...
Is there a way I can explicitly tell the code, either in the Python or the Django/ HTML not to display a certain column of the table when a particular condition is met?
First of all you can pass to the template some variable through the context and check if it was pre or post deposit.
if(project.deposit_received == True):
context['post_deposit'] = True
return render(request, 'costing/reports_post_deposit.html', context)
elif(project.deposit_received == False):
context['post_deposit'] = False
return render(request, 'costing/reports_pre_deposit.html', context)
So now yoou need to check this value in template:
{% if post_deposit %}
do_something
{% else %}
do_something_else
{% endif %}
And the last one you can check current iteration of cycle in template using forloop.counter. For example if you need to remove 3rd column in post_deposit table you can check if the loop counter equal to 3 and skip iteration:
{% for detail in payment_details %}
{% if not post_deposit or forloop.counter != 3 %}
<th>{{ detail.0 }}</th>
{% endif %}
{% endfor %}

Django - How to check if id contains in a table column?

guys.
I want to check in my django template, if request.user exists in some row of column user in my table LeagueMember. The way I found is not working.
views.py
#login_required(login_url='login/')
def search_leagues(request):
if request.method == 'POST':
return redirect('join_league')
leagues = League.objects.all()
return render(request, 'search_leagues.html', { 'allleagues': leagues })
model.py
class League(models.Model):
league_owner = models.ForeignKey('auth.User')
league_name = models.CharField(max_length=30)
creation_date = models.DateTimeField()
def is_member(self):
member = LeagueMember.objects.get(league=self)
if member:
return True
else:
return False
class LeagueMember(models.Model):
league = models.ForeignKey('League', related_name='leaguemember_league')
user = models.ForeignKey('auth.User')
search_leagues.html
{% for league in allleagues %}
<tr>
<td class="center">{{ league.league_name }}</td>
<td class="center">{{ league.leaguemember_league.count}}/{{ league.leaguesettings_league.league_number_teams }}</td>
<td class="center">{{ league.leaguesettings_league.league_eligibility }}</td>
<td class="center">{{ league.leaguesettings_league.league_lifetime }}</td>
{% if request.user in league.leaguemember_league.user %}
DO SOMETHING!!!
{% else %}
{% if league.leaguemember_league.count < league.leaguesettings_league.league_number_teams %}
{% if league.leaguesettings_league.league_eligibility == "Private" %}
<form method="post" action="{% url 'joinleague' pk=league.id %}">
<td class="center">Soliticar</td>
</form>
{% elif league.leaguesettings_league.league_eligibility == "Public" %}
<form method="post" action="{% url 'joinleague' pk=league.id %}">
<td class="center">Entrar</td>
</form>
{% endif %}
{% endif %}
{% endif %}
</tr>
{% endfor %}
This error is in this line:
{% if request.user in league.leaguemember_league.user %}
Always goes to ELSE block
Thank you all
league.leaguemember_league will not give you a LeagueMember object but a RelatedManager object (so you cannot find a user property in it, therefore your template logic will not work).
What you are trying to do is go two levels deep in your relationship (League -> LeagueMember -> User). You can't easily do this kind of logic in your template and probably need to do it in your view code instead. For example:
league_data = []
for league in League.objects.all():
league_data.append({
'league': league,
'users': User.objects.filter(leaguemember__league=league) # This gives you all the users that are related to this league
})
return render(request, 'search_leagues.html', { 'allleagues': league_data})
You then need to modify all your template logic to use this new structure:
{% for league_data in allleagues %}
# Replace league with league_data.league in all the template logic below this
In the if block you can then do:
{% if request.user in league_data.users %}
Note that this querying may not be very efficient if you have a large number of users/leagues - in which case you may need to rethink your model design.

Categories

Resources