I am trying to create a webpage using Django where my database consists thousands of CVEs and display the list of CVEs based on what I typed in the search bar. So far, the search function is working perfectly and it displays the paginated results. But when I try to navigate to next page, it will show a blank page. Below is the code of my views.py and template.
views.py
def search_cve(request):
if request.method == 'GET':
searched = request.GET.get('searched')
if searched:
cve_search = BDSA.objects.filter(cve_id__icontains=searched)
paginator = Paginator(cve_search.order_by('-cve_id'), 10) # show 10 per page
try:
page = int(request.GET.get('page', '1'))
except:
page = 1
try:
cves = paginator.page(page)
except:
cves = paginator.page(1)
index = cves.number - 1
max_index = len(paginator.page_range)
start_index = index - 2 if index >= 2 else 0
end_index = index + 2 if index <= max_index - 2 else max_index
page_range = list(paginator.page_range)[start_index:end_index]
return render(request, 'QueryService/search_cve.html', {'searched':searched, 'cve_search':cve_search, 'cves': cves, 'page_range': page_range})
else:
return render(request, 'QueryService/search_cve.html', {})
template
<body>
{% block content %}
<br/>
<center>
<h1>Searched for: {{ searched }}</h1>
<br/>
<div class="container">
<table class="table table-hover table-striped table-bordered">
{% for cve in cves %}
<tr>
<td>{{ cve }}</td>
</tr>
{% endfor %}
</table>
</div>
<br/>
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
{% if cves.has_previous %}
<li class="page-item"><a class="page-link" href="?page=1">« First</a></li>
<li class="page-item"><a class="page-link" href="?page={{ cves.previous_page_number }}">Prev</a></li>
{% endif %}
{% for pg in page_range %}
{% if cves.number == pg %}
<li class="page-item"><a class="page-link" href="?page={{ pg }}" class="btn btn-default">{{ pg }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ pg }}" class="btn">{{ pg }}</a></li>
{% endif %}
{% endfor %}
{% if cves.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ cves.next_page_number }}">Next</a></li>
<li class="page-item"><a class="page-link" href="?page={{ cves.paginator.num_pages }}">Last »</a></li>
{% endif %}
</ul>
</nav>
<br/><br/>
</center>
{% endblock %}
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
</body>
Any idea on how to fix this?
Nevermind I got the fix! I added this code in the href element of the pagination.
&searched={{ searched }}
For example:
href="?page=1&searched={{ searched }}
Related
views.py
import datetime
from .filters import MyModelFilter
from django.shortcuts import render
import pymysql
from django.http import HttpResponseRedirect
from facligoapp.models import Scrapper
from django.db.models import Q
from django.utils import timezone
import pytz
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
users = ""
def index(request):
if request.method == "POST":
from_date = request.POST.get("from_date")
f_date = datetime.datetime.strptime(from_date,'%Y-%m-%d')
print(f_date)
to_date = request.POST.get("to_date")
t_date = datetime.datetime.strptime(to_date, '%Y-%m-%d')
print(t_date)
get_records_by_date = Scrapper.objects.all().filter(Q(start_time__date=f_date)|Q(end_time__date=t_date))
print(get_records_by_date)
filtered_dates = MyModelFilter(request.GET,queryset=get_records_by_date)
page = request.GET.get('page', 1)
paginator = Paginator(filtered_dates.qs, 5)
global users
try:
users = paginator.get_page(page)
except PageNotAnInteger:
users = paginator.page(1)
except EmptyPage:
users = paginator.page(paginator.num_pages)
else:
roles = Scrapper.objects.all()
page = request.GET.get('page', 1)
paginator = Paginator(roles, 5)
try:
users = paginator.page(page)
except PageNotAnInteger:
users = paginator.page(1)
except EmptyPage:
users = paginator.page(paginator.num_pages)
return render(request, "home.html", {"users": users})
return render(request, "home.html", {"users": users})
filters.py:
import django_filters
from.models import Scrapper
class MyModelFilter(django_filters.FilterSet):
class Meta:
model = Scrapper
# Declare all your model fields by which you will filter
# your queryset here:
fields = ['start_time', 'end_time']
home.html
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<body>
<style>
h2 {text-align: center;}
</style>
<h1>Facilgo Completed Jobs</h1>
<form action="" method="post">
{% csrf_token %}
<label for="from_date">From Date:</label>
<input type="date" id="from_date" name="from_date">
<label for="to_date">To Date:</label>
<input type="date" id="to_date" name="to_date">
<input type="submit"><br>
</form>
<div class="container">
<div class="row">
<div class="col-md-12">
<h2>Summary Details</h2>
<table id="bootstrapdatatable" class="table table-striped table-bordered" width="100%">
<thead>
<tr>
<th>scrapper_id</th>
<th>scrapper_jobs_log_id</th>
<th>external_job_source_id</th>
<th>start_time</th>
<th>end_time</th>
<th>scrapper_status</th>
<th>processed_records</th>
<th>new_records</th>
<th>skipped_records</th>
<th>error_records</th>
</tr>
</thead>
<tbody>
{% for stud in users %}
{% csrf_token %}
<tr>
<td>{{stud.scrapper_id}}</td>
<td>{{stud.scrapper_jobs_log_id}}</td>
<td>{{stud.external_job_source_id}}</td>
<td>{{stud.start_time}}</td>
<td>{{stud.end_time}}</td>
<td>{{stud.scrapper_status}}</td>
<td>{{stud.processed_records}}</td>
<td>{{stud.new_records}}</td>
<td>{{stud.skipped_records}}</td>
<td>{{stud.error_records}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if users.has_other_pages %}
<ul class="pagination">
{% if users.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% if user.number|add:'-4' > 1 %}
<li>…</li>
{% endif %}
{% for i in users.paginator.page_range %}
{% if users.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% elif i > users.number|add:'-5' and i < users.number|add:'5' %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if users.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
{% endif %}
</div>
</div>
</div>
</body>
</html>
I need to get only the datas which I have filtered et_records_by_date = Scrapper.objects.all().filter(Q(start_time__date=f_date)|Q(end_time__date=t_date)) in pagination. But when I click the next page its showing different datas. Is there any solution to get only the datas for the particular query. When I post the datas the of dates the 1st pages is showing the correct details but when I click page 2 its showing the other datas
When you click on 'next page' you're performing a GET request, and not a POST request. Which means it will go into the else block, which has no filtering but just returns all the Scrapper objects.
You're better off including the from_date and to_date in a GET request and not using a POST request.
If you're using a form you can simply set the method:
<form method="GET" action="..." />
Shared method
def paginate(request,obj,total=25):
paginator = Paginator(obj,total)
try:
page = int(request.GET.get('page', 1))
except:
page = 1
try:
obj_list = paginator.page(page)
except(EmptyPage,InvalidPage):
obj_list = paginator.page(paginator.num_pages)
return obj_list
View
users = UserInfo.objects.all()
data = {
'users': paginate(request,users,15),
}
return render(request,self.template_name,data)
HTML
{% include './pagination.html' with obj=users %}
pagination.html file
{% if obj.paginator.num_pages > 1 %}
<div class="text-center">
<ul class="pagination">
<li class="{% if not obj.has_previous %} disabled{% endif %}">
{% if obj.has_previous %}
<a data-page="{{obj.previous_page_number}}" href="?page={{obj.previous_page_number}}{% for key, value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}" aria-label="{% trans 'Previous' %}" tabindex="-1"> « </a>
{% else %}
<a data-page="0" class="" href="javascript:void(0);" tabindex="-1">«</a>
{% endif %}
</li>
{% for i in obj.paginator.page_range %}
{% if obj.number == i %}
<li class="active">
<a data-page="0" class="" href="javascript:void(0)">{{ i }}</a>
</li>
{% elif i > obj.number|add:'-5' and i < obj.number|add:'5' %}
<li class=""><a data-page="{{i}}" class="" href="?page={{i}}{% for key, value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">{{ i }}</a>
</li>
{% endif %}
{% endfor %}
<li class="{% if not obj.has_next %} disabled{% endif %}">
{% if obj.has_next %}
<a data-page="{{ obj.next_page_number }}" class="" href="?page={{obj.next_page_number}}{% for key, value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}" tabindex="-1">»</a>
{% else %}
<a data-page="0" class="" href="javascript:void(0);" tabindex="-1">»</a>
{% endif %}
</li>
</ul>
</div>
{% endif %}
I made a blog app in which I want to add pagination both on home page and category page. but after a lot of efforts I didn't get how to use it in the category page. I use 2 parameters in category view and I don' know how to fix it now. whenever I click on category "That page number is not an integer" displays.
views.py:
def allpost(request):
postData = Post.objects.all()
paginator = Paginator(postData, 5) # Show 5 contacts per page.
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'posts.html', {'page_obj': page_obj})
def CategoryView(request, cats='category__title'):
category_posts = Post.objects.all()
paginator = Paginator(category_posts, 5)
# We don't need to handle the case where the `page` parameter
# is not an integer because our URL only accepts integers
try:
category_posts = paginator.page('cats')
except EmptyPage:
# if we exceed the page limit we return the last page
category_posts = paginator.page(paginator.num_pages)
return render(request, 'categories.html', {'category_posts': category_posts})
urls.py:
path('category/<str:cats>/', views.CategoryView, name ="category"),
categories.html
{% extends 'base.html' %}
{%block content%}
<h1> Category: {{ cats }} </h1>
{% for post in category_posts %}
<div class="container mt-3">
<div class="row mb-2">
<div class="col-md-6">
<div class="card flex-md-row mb-4 box-shadow h-md-250">
<div class="card-body d-flex flex-column align-items-start">
<strong class="d-inline-block mb-2 text-primary">{{ post.category }}</strong>
<h3 class="mb-0">
<a class="text-dark" href="{% url 'detail' post.id %}">{{post.title}}</a>
</h3>
<div class="mb-1 text-muted">{{ post.public_date }}</div>
<p class="card-text mb-auto">{{ post.summary }}</p>
Continue reading
</div>
<img class="card-img-right flex-auto d-none d-md-block" data-src="holder.js/200x250?theme=thumb" alt="Thumbnail [200x250]" style="width: 200px; height: 250px;" src="data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22200%22%20height%3D%22250%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20200%20250%22%20preserveAspectRatio%3D%22none%22%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%23holder_182c981dfc3%20text%20%7B%20fill%3A%23eceeef%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A13pt%20%7D%20%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_182c981dfc3%22%3E%3Crect%20width%3D%22200%22%20height%3D%22250%22%20fill%3D%22%2355595c%22%3E%3C%2Frect%3E%3Cg%3E%3Ctext%20x%3D%2256.20000076293945%22%20y%3D%22131%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E" data-holder-rendered="true">
</div>
</div>
</div>
</div>
{% endfor %}
{% include 'pagination.html' %}
{%endblock%}
pagination.html
<div class="container mt-3">
<nav aria-label="Page navigation example">
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item"><a class="page-link" href="/?page=1">First</a></li>
<li class="page-item"><a class="page-link" href="/?page={{ page_obj.previous_page_number }}">Previous</a></li>
{% endif %}
<li class="page-item"><a class="current" href="/?page={{ page_obj.number }} of {{ page_obj.paginator.num_pages }}">1</a></li>
{% if page_obj.has_next %}
<li class="page-item"><a class="page-link" href="/?page={{ page_obj.next_page_number }}">Next</a></li>
<li class="page-item"><a class="page-link" href="/?page={{lastpage}}">Last</a></li>
{% endif %}
</div>
I am very confused already in category views function to use parameter issue. so that I didn't use that code in pagination.html.
===== in view.py ======
from django.core.paginator import Paginator
def HomeView(request):
show_data = VehicleModel.objects.all() # Queryset For pagiantion
# Pagination code start
paginator = Paginator(show_data, 3, orphans=1)
page_number = request.GET.get('page')
show_data = paginator.get_page(page_number)
# Pagination code end
context = {'page_number':page_number}
return render(request,'dashboard.html',context)
===== in html file ======
<!-- Pagination Block with page number -->
<div class="container mt-5">
<div class="row float-right ">
<span class="m-0 p-0">
{% if carset.has_previous %} # <!-- For Previous Button -->
<a class="btn btn-outline-info" href="?page={{carset.previous_page_number}}&ok=#ok">Previous</a>
{% endif %}
<span>{% for pg in carset.paginator.page_range %} # <!-- For Page Numbers Buttons -->
{% if carset.number == pg %}
<a href="?page={{pg}}" class="btn btn-sm btn-primary">
<span class="badge">{{pg}}</span>
</a>
{% else %}
<a href="?page={{pg}}" class="btn btn-sm btn-secondary">
<span class="badge">{{pg}}</span>
</a>
{% endif %}
{% endfor %}</span>
{% if carset.has_next %} # <!-- For Next Button -->
<a class="btn btn-outline-info" href="?page={{carset.next_page_number}}&ok=#ok">Next</a>
{% endif %}
</span>
</div>
</div>
=========== Your code is like this ==============
here you passed the category parameter in the function so must pass the category title with the calling URL of this CategoryView(request, cats='category__title') function
def CategoryView(request, cats='category__title'):
category_posts = Post.objects.all()
paginator = Paginator(category_posts, 5)
with this CategoryView(request, cats='category__title') you want all Posts ???
def
CategoryView(request, cats='category__title'):
category_posts = Post.objects.filter(cats__title = cats)
paginator = Paginator(category_posts, 5)
ator = Paginator(category_posts, 5)
urls.py
urlpatterns = [
path('',CourseList.as_view(),name='course_list'),
path('create/',CourseCreate.as_view(),name='course_create'),
path('<int:cid>/',CourseView.as_view(),name='course_view'),
]
views.py
COURSE_PERM_GUEST = 0
COURSE_PERM_STUDENT = 1
COURSE_PERM_TEACHER = 2
COURSE_PERM_MEMBER = 3
class CourseAccessMixin(AccessMixin):
permission = None
extra_context = {}
def dispatch(self,request,*args,**kwargs):
if not request.user.is_authenticated:
return super().handle_no_permission()
self.course = get_object_or_404(Course,id=kwargs['cid'])
user_perm = COURSE_PERM_GUEST
if self.course.teacher == request.user:
user_perm = COURSE_PERM_TEACHER
elif self.course.enroll_set.filter(student=request.user).exists():
user_perm = COURSE_PERM_STUDENT
if not request.user.is_superuser and self.permission is not None:
is_accessible = False
if self.permission == COURSE_PERM_GUEST and \
user_perm == COURSE_PERM_GUEST:
is_accessible = True
elif (self.permission & user_perm) != 0:
is_accessible = True
if not is_accessible:
return super().handle_no_permission()
self.extra_context.update({'course':self.course})
return super().dispatch(request,*args,**kwargs)
class CourseView(CourseAccessMixin,DetailView):
extra_context = {'title':'檢視課程'}
model = Course
pk_url_kwarg = 'cid'
models.py
class Course(models.Model):
name = models.CharField('課程名稱',max_length=50)
enroll_password = models.CharField('選課密碼',max_length=50)
teacher = models.ForeignKey(User,models.CASCADE)
def __str__(self):
return '{}#{} ({})'.format(
self.id,
self.name,
self.teacher.first_name)
course_list.html
{% extends "base.html" %}
{% load user_tags %}
{% block content %}
{% if user|is_teacher %}
<div class="mb-2">
建立課程
</div>
{% endif %}
<div id="course_list">
{% for course in course_list %}
<div class="list-group">
<div class="list-group-item d-flex">
{% if user.is_authenticated %}
{{ course.name }}
{% else %}
{{ course.name }}
{% endif %}
<small class="ml-auto">{{ course.teacher.first_name }} 老師</small>
</div>
</div>
{% endfor %}
</div>
{% include 'pagination.html' %}
{% endblock %}
course_detail.html
{% extends 'base.html' %}
{% load user_tags %}
{% block content %}
<div id="course_view" class="card">
{% with b1 = "btn btn-sm btn-primary" b2 = "btn btn-sm btn-secondary" %}
<div class="card-header d-flex">
<div>
{{ course.name }}
<small>{{ course.teacher.first_name }} 老師</small>
</div>
{% if user.is_superuser or course.teacher == user %}
<div class="ml-auto">
<span class="badge badge-light">
選課密碼: {{ course.enroll_password }}
</span>
<a href="{% url 'course_edit' course.id %}" class="{{ b1 }}">
<i class="fas fa-edit"></i>編輯
</a>
</div>
{% endif %}
</div>
<div class="card-body">
{% block course_detail_body %}
<div id="student_op" class="btn-group">
{% if not course|has_member:user and not user.is_superuser %}
<a href="{% url 'course_enroll' course.id %}" class="{{ b1 }}">
<i class="fas fa-id-badge"></i>選修
</a>
{% else %}
<a href="{% url 'course_users' course.id %}" class="{{ b1 }}">
<i class="fas fa-users"></i>修課名單
</a>
{% if course|has_student:user %}
<a href="{% url 'course_seat' course.id %}" class="{{ b1 }}">
<i class="fas fa-chair"></i>更改座號
</a>
{% endif %}
{% endif %}
</div>
{% endblock %}
</div>
{% endwith %}
</div>
{% endblock %}
Error:
ValueError at /course/1/
The view course.views.CourseView didn't return an HttpResponse object. It returned None instead.
I had a view CourseView and when I try to access the detail of the corresponding course by clicking the hyperlink {{ course.name }} from the template course_list.html, I received the error message showing that it didn't return an HttpResponse object. I do not know what is missing in order to have the details accessible even though I had set the pk_url_kwarg?
You forget to add return super().dispatch(request,*args,**kwargs) and the end of dispatch function (you add it, only in if condition)
change this
self.extra_context.update({'course':self.course})
return super().dispatch(request,*args,**kwargs)
To this:
self.extra_context.update({'course':self.course})
return super().dispatch(request,*args,**kwargs)
return super().dispatch(request,*args,**kwargs)
I am setting up a pagination in my Django APP. Following is my view code:
class ClaimsView(ListView):
context_object_name = "archives"
template_name = "myapp/claims.html"
def get_queryset(self, **kwargs):
query = self.request.GET.get("q", "")
response = self.get_archives(query)
paginator =Paginator(response, 4)
pages = paginator.get_pages(4)
return {'archives': response, 'pages': pages}
When I print pages in the viwes file. It give correct result "<page 1 of 1>"
but when I am passing it to the HTML file its not give any results there.
'archives' in above dict has a list as value its working fine but not the 'pages'
This is how I am reading it in HTML file:
{{pages}}
get queryset method should always return a list or queryset not a dictionary. for pagination...in get of your listview do something like this
def get(self, *args, **kwargs):
context = {}
response = "your queryset"
paginator_obj=Paginator(response,4)
page_number=self.request.GET.get('page',1)
students=paginator_obj.get_page(page_number)
context["page_obj"] = paginator_obj
if self.request.get_full_path().endswith('/'):
fullpath = self.request.get_full_path()+'?page='
else:
fullpath = self.request.get_full_path()
context['fullpath'] = fullpath
context['object_list'] = response
return render(self.request, self.template_name, context)
in your template do something like this
<div class="text-center">
{% if object_list.has_other_pages %}
<ul class="pagination" style="text-align:center; width:100% ;justify-content: center!important;">
{% if object_list.has_previous %}
<li class="page-item"><a class="page-link" href="{{ fullpath }}&page={{ page_obj.previous_page_number }}">«</a></li>
{% else %}
<li class="page-item" class="disabled"><span class="page-link">«</span></li>
{% endif %}
{% for i in object_list.paginator.page_range %}
{% if object_list.number == i %}
<li class="page-item"class="active"><span class="page-link">{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li class="page-item"><a class="page-link" href="{{ fullpath }}&page={{ i }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if object_list.has_next %}
<li class="page-item"><a class="page-link" href="{{ fullpath }}&page={{ page_obj.next_page_number }}">»</a></li>
{% else %}
<li class="page-item" class="disabled"><span class="page-link">»</span></li>
{% endif %}
</ul>
{% endif %}
</div>
I'd like to display << 1 2 3 4... 11 12 >> instead of << 1 2 3 4 5 6 7 8 9 10 11 12>> in my Django site and using pagination.
This is what I get currently :
My html code :
<div class="row">
<div class="col-md-12">
{% if jokes.has_other_pages %}
<ul class="pagination">
{% if jokes.has_previous %}
<li class="page-item">
«
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link">«</a>
</li>
{% endif %}
{% for i in jokes.paginator.page_range %}
{% if jokes.number == i %}
<li class="page-item active">
<a class="page-link">{{i}}</a>
</li>
{% else %}
<li class="page-item">
{{i}}
</li>
{% endif %}
{% endfor %}
{% if jokes.has_next %}
<li class="page-item">
»
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link">»</a>
</li>
{% endif %}
</ul>
{% endif %}
</div>
Thanks in advance !
Here is a flask example, which should give you a good starting point:
<div style="margin:25px 20% 100px 20%;">
{% for page_num in posts.iter_pages(left_edge=1, right_edge=1, left_current=1, right_current=2) %}
{% if page_num %}
{% if posts.page == page_num %}
<a class="btn btn-info mb-4" href=" {{ url_for('myposts', page=page_num) }}">{{ page_num }}</a>
{% else %}
<a class="btn btn-outline-info mb-4" href=" {{ url_for('myposts', page=page_num) }}">{{ page_num }}</a>
{% endif %}
{% else %}
...
{% endif %}
{% endfor %}
</div>
you can use it like this
{% if jokes.has_previous %}
first
{{ jokes.previous_page_number }}
{% endif %}
<span class="current">
{{ jokes.number }}
</span>
{% if jokes.has_next %}
{{ jokes.next_page_number }}
last
{% endif %}
it will result like:
first 4 5 6 last
4 is previous page
5 is current page
6 is next page