How to access values for a key in a Django template? - django

Newbie Question:
I have a dictionary rendering with extra_Context from a method defined in views.py
My views:
extra_context = {
'comment': comment
}
return direct_to_template(request, 'events/comment_detail.html', extra_context)
If i print the comment the it print like this:
[{'comment': u'first', 'user': 2}, {'comment': u'second', 'user': 2}]
I want to pass this dictionary to my template. I tried with this following code:
<tbody>
{% for obj in comment %}
{% for key,val in obj.items %}
<tr class="{% cycle 'odd' 'even' %}">
<td> {{val}}</td>
</tr>
{% endfor %}
{% endfor %}
</tbody>
It prints :
first
2
second
2
I want in this way:
first 2
second 2
..and so on
What should i add it to get like above ?
Updated!
def comment_detail(request, object_id):
comment_obj = EventComment.objects.filter(event = object_id)
comment = comment_obj.values('comment','user')
extra_context = {
'comment': comment
}
return direct_to_template(request, 'events/comment_detail.html', extra_context)
comment_detail.html
<form action="" method="POST">
<table>
<thead>
<tr><th>{% trans "Comments" %}</th><th>{% trans "Timestamp "%}<th>{% trans "User" %}</th></tr>
</thead>
<tbody>
{% if comments %}
{% for com in comment %}
<td> {{com.comment}}</enter code heretd>
<td> {{com.user}}</td>
{% endfor %}
{% else %}
<td> No comments </td>
{% endif %}
</tr>
</tbody>
</table>
</form>

You don't need that nested for iterating k,v. I just tried this:
View:
def testme(request):
comments = []
comments.append({'user': 2, 'comment': 'cool story bro'})
comments.append({'user': 7, 'comment': 'yep. cool story'})
extra_context = {
'comments': comments
}
return render_to_response('testapp/testme.html', extra_context )
Template:
{% if comments %}
<b>Comments:</b>
<ul>
{% for comment in comments %}
<li>{{ comment.comment }} (id {{ comment.user }})</li>
{% endfor %}
</ul>
{% else %}
<b>No comments</b>
{% endif %}

"for k(k=key), v(v=value) in object.items"
All that is saying is to iterate over every key value pair i.e. such as name = models.CharField(max_length=50) in object.items. Your view has returned context for object.items which each item is a model instance and has a set of k,v pairs associated with it.

Looks like your question just about html markup.
Try this:
<tbody>
{% for obj in comment %}
<tr class="{% cycle 'odd' 'even' %}">
{% for key,val in obj.items %}
<td>{{val}}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
or this:
<tbody>
{% for obj in comment %}
<tr class="{% cycle 'odd' 'even' %}"><td>
{% for key,val in obj.items %}
{{val}}<span> </span>
{% endfor %}
</td> </tr>
{% endfor %}
</tbody>

Related

Pagination doesn`t work with extra context in Django ListView

I am trying to create a simple pagination through a query of filtered instances of Need model.
The problem is that pagination doesn`t work at all, and I guess this is because of extra content.
Here is my current view, which shows pagination on front-end as an empty div:
class CategoryNeeds(ListView):
model = Need
template_name = "volunteering/category_needs.html"
paginate_by = 1
context_object_name = "needs"
def get_queryset(self):
return Need.objects.filter(category__name=self.kwargs["name"].capitalize())
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
category = Category.objects.get(name=kwargs["name"].capitalize())
self.extra_context = {
"category": category,
"needs": self.object_list
}
return self.render_to_response(self.extra_context)
And here is the template:
{% extends "index/index.html" %}
{% block content %}
<section class="contact-section bg-black">
<div class="container px-4 px-lg-5">
<div class="row gx-4 gx-lg-5">
<div class="col-md-4 mb-3 mb-md-0">
<div class="card-body text-center">
<h1>{{ category.name }}</h1>
<hr style="size: A5">
</div>
</div>
</div>
</div>
</section>
<section class="about-section text-center" id="about">
<div class="container px-4 px-lg-5">
<h2>Needs:</h2>
<table class="table table-dark table-striped">
<thead>
<tr>
<th scope="col">Photo</th>
<th scope="col">Title</th>
<th scope="col">Description</th>
<th scope="col">Price</th>
<th scope="col">Donation</th>
<th scope="col">City</th>
{% if user.pk == user_page.pk %}
<th scope="col">Update</th>
<th scope="col">Delete</th>
{% endif %}
</tr>
</thead>
<tbody>
{% for need in needs %}
<tr data-href="{% url "volunteering:need" need.pk %}">
<td>{% if need.photo %}<img src="{{ need.photo.url }}">{% endif %}</td>
<td>{{ need.title }}</td>
<td>{{ need.description|truncatechars:10 }}</td>
<td>{{ need.price }}</td>
<td>{{ need.donation }}</td>
<td>{{ need.city }}</td>
{% if user.pk == user_page.pk %}
<td>Update</td>
<td>Delete</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div>
{% if page_obj.has_previous %}
« Previous page
{% if page_obj.number > 3 %}
1
{% if page_obj.number > 4 %}
<span>...</span>
{% endif %}
{% endif %}
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
{{ num }}
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
{{ num }}
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
{% if page_obj.number < page_obj.paginator.num_pages|add:'-3' %}
<span>...</span>
{{ page_obj.paginator.num_pages }}
{% elif page_obj.number < page_obj.paginator.num_pages|add:'-2' %}
{{ page_obj.paginator.num_pages }}
{% endif %}
Next Page »
{% endif %}
</div>
</section>
{% endblock %}
The reason why I think the problem lies in extra content is because this view works perfectly with pagination:
class AllNeeds(ListView):
model = Need
context_object_name = "needs"
paginate_by = 3
Could someone explain, why doesn`t my pagination work, please?
Would be very grateful for all your responce!
Yep, it seems that you are overiding normal django flow which adds context, try this:
class CategoryNeeds(ListView):
model = Need
template_name = "volunteering/category_needs.html"
paginate_by = 1
def get_queryset(self):
return Need.objects.filter(category__name=self.kwargs["name"].capitalize())
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
category = Category.objects.get(name=kwargs["name"].capitalize())
context = self.get_context_data()
context['category'] = category
return self.render_to_response(context)

Django pagination not showing using class base view

Hi looking for a solution and yet nothing solve to my problem, I do not know why but it is not showing the paginate number in html file. here is structure code:
class ListEmployeeActivity(ListView, LoginRequiredMixin):
paginate_by = 1
model = EmployeePersonalDetailsModel
template_name = 'layout/employee_list_layout.html'
context_object_name = 'datalist'
def get_queryset(self):
return self.model.objects.prefetch_related('ecdm_fk_rn').all()
html file:
{% if is_paginated %}
<div class="pagination pagination-centered">
<ul>
{% if datalist.has_previous %}
<li><i class="icon-double-angle-left"></i></li>
{% endif %}
{% for total_pages in datalist.paginator.page_range %}
<li>1</li>
{% endfor %}
{% if datalist.has_next %}
<li><i class="icon-double-angle-right"></i></li>
<li>Last</li>
{% endif %}
</ul>
</div>
{% else %}
<h3>Pagination not working.</h3>
{% endif %}
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
class UserListView(ListView):
model = User
template_name = 'core/user_list.html'
context_object_name = 'users'
paginate_by = 10
queryset = User.objects.all()
HTML file.
<table class="table table-bordered">
<thead>
<tr>
<th>Username</th>
<th>First name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.username }}</td>
<td>{{ user.first_name }}</td>
<td>{{ user.email }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
user this for refernace

django Pagination with Class-Based Views

How do i create pagination in Django ListView? and i just want that per page have 5 records only
this is my views.py
class ArticleListView(ListView):
model = StudentsEnrollmentRecord
template_name = 'Homepage/studentsenrollmentrecord_list.html'
paginate_by = 5
queryset = StudentsEnrollmentRecord.objects.all()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return(context)
and this is my html search_and_page.html
<table id="customers">
<tr>
<th>Username</th>
<th>Firstname</th>
<th>Email</th>
</tr>
{% for article in object_list %}
<tr id="myAnchor">
<td class="grpTextBox">{{ article.username }}</td>
<td class="grpTextBox">{{ article.Firstname }}</td>
<td class="grpTextBox">{{article.Email}}</td>
</tr>
{% endfor %}
</table>
in web view
I think you miss out this
check out this documentation https://simpleisbetterthancomplex.com/tutorial/2016/08/03/how-to-paginate-with-django.html
<center>
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item">«</li>
{% else %}
<li class="disabled page-item"><span>«</span></li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="active page-item"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li class="page-item">{{ i }}</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li>»</li>
{% else %}
<li class="disabled page-item"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
</center>

I was going to render the saved data into html table but found this error

<tbody>
{% for publication in publication_list %}
<tr>
<td>{{%publication.addpublication%}}</td>
</tr>
{% endfor %}
</tbody>
views.py
def publicationlist(request):
context = {'publication_list' : AddPublication.objects.all()}
return render(request,"publication_list.html", context)
TemplateSyntaxError at /addpublication/publicationlist/
Could not parse the remainder: '%publication.addpublication%' from '%publication.addpublication%'
# You have to remove % in your td tag of html
<tbody>
{% for publication in publication_list %}
<tr>
<td>{{publication.addpublication}}</td>
</tr>
{% endfor %}
</tbody>
For tags like for, if...:
{% for %}{% endfor %}
For context variables:
{{ my_context_variable }}

First row with two items second one and next with three

I have model (Event) and I want to have template with two ways to display items.
First row have to include two items, with special styling
Second one and next have to include three, with special styling
How can I do this with loop?
you can do like below
views.py
def view(request):
events = Event.objects.all()
l = []
for i in range(0,len(events), 5):
l.append((events[i:i+2], events[i+2:i+5]))
return render(request, "template.html", {"events": l})
template.html
{% for two_items, three_items in events %}
<tr class="class1">
{% for item in two_items %}
<td> {{ item }}</td>
{% endfor %}
<tr>
<tr class="class2">
{% for item in three_items %}
<td> {{ item }}</td>
{% endfor %}
<tr>
{% endfor %}
Combination of cycle and forloop tags will give you desired output:
For example:
{% for item in items %}
{% if forloop.counter < 3 %}
{% if forloop.first %}
<tr class="A">
{% endif %}
<td>{{ item }}</td>
{% endif %}
{% if forloop.counter == 3 %}
</tr>
{% endif %}
{% if forloop.counter >= 3 %}
{% cycle "<tr class='B'>" "" "" %}
<td>{{ item }}</td>
{% cycle "" "" "</tr>" %}
{% endif %}
{% endfor %}