Django pagination not showing using class base view - django

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

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

Displaying label on first form of Django formset only

This is a super straightforward question but I can't seem to find any concise answer it. I have a Django formset that displays different tags associated with an object. Here is the form:
class TagForm(forms.Form):
def __init__(self, *args, **kwargs):
tags = kwargs.pop('tags')
super(TagForm, self).__init__(*args, **kwargs)
self.fields['tags'] = forms.ChoiceField(choices=[(tag, tag) for tag in tags], label="Tags")
I'm rendering the formset using the following code:
<li class="list-group-item">
<ul class="list-inline" id="tag-group">
{{ tag_formset.management_form }}
{% for tag_form in tag_formset %}
<li class="list-inline-item">
{{ tag_form.tags.label_tag }}
{{ tag_form.tags }}
</li>
{% endfor %}
</ul>
</li>
My problem is that this creates a label for each tag. Since this is an inline list, I'd only like to display the label prior to the first tag (and no others). I can't find any straightforward way to do this (without modifying the for loop with explicit logic checking if it is the first form being rendered). I optimistically tried to modify my rendering code to the following:
<li class="list-group-item">
<ul class="list-inline" id="tag-group">
{{ tag_formset.management_form }}
{{ tag_form.empty_form.label_tag }}
{% for tag_form in tag_formset %}
<li class="list-inline-item">
{{ tag_form.tags }}
</li>
{% endfor %}
</ul>
</li>
but this didn't display any labels at all. Is there an idiomatic way to only display the form label prior to the first form in a formset?
The code below is working for me. The main idea is simple. Make a Table and in the headers put the tags. and in the table body put only the data. Try it and let me know.
{% for f1 in formset %}
{{ f1.management_form|crispy }}
{% crispy f1 %}
{% endcomment %}
<table{% if form_id %} id="{{ form_id }}_table" {% endif%} class="table table-striped table-condensed">
<thead>
{% if formset.readonly and not formset.queryset.exists %}
{% else %}
<tr>
<td>
</td>
{% for field in formset.forms.0 %}
{% if field.label and not field.is_hidden %}
<th for="{{ field.auto_id }}"
class="control-label {% if field.field.required %}requiredField{% endif %}">
{{ field.label|safe }}{% if field.field.required %}<span
class="asteriskField">*</span>{% endif %}
</th>
{% endif %}
{% endfor %}
</tr>
{% endif %}
</thead>
<tbody>
{% comment %} <tr class="hidden empty-form">
{% for field in formset.empty_form %}
{% include 'bootstrap/field.html' with tag="td" form_show_labels=False %}
{% endfor %}
</tr> {% endcomment %}
{% for form2 in formset2 %}
{% if form2_show_errors and not form2.is_extra %}
{% include "bootstrap/errors.html" %}
{% endif %}
<tr>
<td>
<a class="btn btn-info pull-right" {% comment %}
href="{% url 'set_final' formfs.pk %}/?next={% url 'update-well-view' form.pk %}">
{% endcomment %}
href="{% url 'Scouts-home' %}"> Set Final
</a>
</td>
{% for field in form2 %}
{% include 'bootstrap/field.html' with tag="td" form2_show_labels=False %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>

Custom formset templates in Django

I am using a Django formset for this model:
class Book(models.Model):
book_id=models.AutoField(primary_key=True,unique=True)
book_name=models.CharField(max_length=30)
publisher_name=models.CharField(max_length=40)
author=models.ForeignKey(Author)
The formset is defined thus:
BookFormset = inlineformset_factory(Author, Book,
fields=('book_id','book_name', 'publisher_name'), extra=1,
can_delete=False)
The template is:
{{ formset.non_form_errors.as_ul }}
<table id="formset" class="form">
{% for form in formset.forms %}
{% if forloop.first %}
<thead><tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}
{% endfor %}
</tr></thead>
{% endif %}
<tr class="{% cycle row1,row2 %}">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
The fields are displayed column-wise, but I would like them to be displayed row-wise.
The above code produces output like this:
Book name Publisher name
book_field Publisher_field
I would like the output to look like this:
Book name book_field
Publisher name Publisher_field
How can I do this?
In your template, you have two <tr> elements, each of which contains a loop over form.visible_fields, each iteration of which generates a single <th> or <td>.
Change this round so that you have a single loop over form.visible_fields, each iteration of which contains a single <tr> element containing a <th> and a <td>. Like this:
<table id="formset" class="form">
{% for form in formset.forms %}
{% for field in form.visible_fields %}
<tr class="{% cycle row1,row2 %}">
<th>{{ field.label|capfirst }}</th>
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
</tr>
{% endfor %}
{% endfor %}
</table>
The examples above seem to show a column-wise layout, which appears to be the default layout when a formset renders itself.
To make it row-wise, use something like this:
<table>
{% for form in formset.forms %}
{% if forloop.first %}
<thead>
{% for field in form.visible_fields %}
<th>{{ field.label }}</th>
{% endfor %}
</thead>
<tbody>
{% endif %}
<tr class="{% cycle row1,row2 %}">
{% for field in form.visible_fields %}
<td>
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% if forloop.last %}
</tbody>
{% endif %}
{% endfor %}
</table>

Django Admin: Customizing the inline template (tabular.html)

I'm trying to follow the guidelines in this answer, but I'm getting stuck with how to edit the template.
The relevant part of my admin.py:
SegmentFormset = forms.models.inlineformset_factory(Division,Segment)
class DivisionForm(forms.ModelForm):
def __init__(self, **kwargs):
super(DivisionForm, self).__init__(**kwargs)
self.segment_formset = SegmentFormset(instance=self.instance, data=self.data,
prefix=self.prefix)
def is_valid(self):
return (super(DivisionForm, self).is_valid() and
self.segment_formset.is_valid())
def save(self, commit=True):
assert commit == True
res = super(DivisionForm, self).save(commit=commit)
self.segment_formset.save()
return res
class DivisionInline(admin.TabularInline):
model = Division
form = DivisionForm
template = 'competitions/admin/tabular.html'
class CompetitionAdmin(VersionAdmin):
inlines = [DivisionInline,]
The relevant part of my template:
{% for fieldset in inline_admin_form %}
{% for line in fieldset %}
{% for field in line %}
<td class="{{ field.field.name }}">
{{ field.field.errors.as_ul }}
{{ field.field }}
</td>
{% endfor %}
{% endfor %}
<td>My segment formset should be here</td>
{% endfor %}
What I can't figure out is how to access the segment formset. I've experimented with all of the variable names and none of them are my DivisionForm. The division formset is the {{fieldset.formset}} variable and that's as far as I've been able to get.
Edit 1:
Actually, the relevant part of the template is a bit longer ;) Putting in more code:
<tbody>
{% for inline_admin_form in inline_admin_formset %}
{% if inline_admin_form.form.non_field_errors %}
<tr><td colspan="{{ inline_admin_form.field_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr>
{% endif %}
<tr class="{% cycle row1,row2 %} {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}">
<td class="original">
{% if inline_admin_form.original or inline_admin_form.show_url %}<p>
{% if inline_admin_form.original %} {{ inline_admin_form.original }}{% endif %}
{% if inline_admin_form.show_url %}{% trans "View on site" %}{% endif %}
</p>{% endif %}
{% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
{{ inline_admin_form.fk_field.field }}
{% spaceless %}
{% for fieldset in inline_admin_form %}
{% for line in fieldset %}
{% for field in line %}
{% if field.is_hidden %} {{ field.field }} {% endif %}
{% endfor %}
{% endfor %}
{% endfor %}
{% endspaceless %}
</td>
{% for fieldset in inline_admin_form %}
{% for line in fieldset.formset %}
{% for field in line %}
<td class="{{ field.field.name }}">
{{ field.field.errors.as_ul }}
{{ field.field }}
</td>
{% endfor %}
{% endfor %}
<td>My segment formset should be here</td>
{% endfor %}
{% if inline_admin_formset.formset.can_delete %}
<td class="delete">{% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}</td>
{% endif %}
</tr>
{% endfor %}
</tbody>
Formsets are like lists, so you can recurse it like
{% for form in fieldset.formset %}
{{ form.as_p }}
{% endfor %}