How to create two pagination in Django for the same page? - django

I have searching on the internet but I did not find a good answer, I would like to know if is possible to create multiple pagination with ListView, like I changed my context to return two list of different objects and then I will put each in a row and each row will have a paginatior for that list.
How should I proceed to achieve this ?
ListView
class IndexView(TemplateView):
template_name = "index.html"
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['oportunities_idea'] = Oportunity.objects.filter(goal_oportunity_idea=True)
context['oportunities_project'] = Oportunity.objects.filter(goal_oportunity_project=True)
return context
index.html
<div class="row mt15"><!--project-->
<div id="home" class="tab-pane row fade in active">
<legend>Projects</legend>
{% for project in oportunities_project %}
<h2>{{project.title}}<h2>
{% if forloop.counter|divisibleby:1 %}
</li>
<li>
{% endif %}
{% endfor %}
</div>
</div>
<div class="row mt15">
<div id="home" class="tab-pane row fade in active">
<legend>Ideas</legend>
{% for idea in oportunities_idea %}
<h2>{{idea.title}}<h2>
{% if forloop.counter|divisibleby:1 %}
</li>
<li>
{% endif %}
{% endfor %}
</div>
</div>

Related

How to display child element in Django MPTT?

I am trying to call parent and child element of a model, I have gone through the MPTT model documentation. I did as mentioned on the documentation, but my template is failing to print children
What can be the possible cause of this problem?
Here is my Views:
def category_view(request):
category = Categories.objects.all()
brands = Brands.objects.all()
context ={
'category':category,
'brands':brands,
}
return render(request,'./ecommerce/categories.html', context)
and Here is my template HTML:
{% load mptt_tags %}
{% recursetree category%}
<div class="category-wrap mb-4">
<div class="category category-group-image br-sm">
<div class="category-content">
<h4 class="category-name">{{ node.name }}
</h4>
<ul class="category-list">
{% if not node.is_leaf_node %}
<li>{{children}}</li>
{% endif %}
</ul>
</div>
</div>
</div>
<!-- End of Category Wrap -->
{% endrecursetree %}
Parent element is printed but children element is not being printed
Doing a lot of hit and trial, generic approach solved my problem. Others having similar problem could be benefited from my answer, hence posting the solution.
Views:
category = Categories.objects.filter(parent=None)
Template:
{% for category in categories %}
<div class="category-wrap mb-4">
<div class="category category-group-image br-sm">
<div class="category-content">
<h4 class="category-name">{{ category.name }}
</h4>
<ul class="category-list">
{% for cat in category.get_children %}
<li>{{ cat.name }} </li>
{% endfor %}
</ul>
</div>
</div>
</div>
<!-- End of Category Wrap -->
{% endfor %}

Django: Certain users get random 404 error

I'm facing a strange issue that I can't handle on my own.
In normal cases when users click on a link, then they are directed to a page where they can edit their hook baits (objects). However, certain users get 404 errors, but I don't know why because the page is rendered for most users.
html where the link is
<div class="row justify-content-center mx-2" >
<div class="col-12 p-0">
<ul class="list-group text-center custom-borders m-2 p-0">
{% if own_hookbaits.count == 0 %}
<a href="{% url 'user_profile:hookbaits' request.user.fisherman.fisherman_id %}" class="list-group-item" >No hook baits yet</a>
{% else %}
{% for hookbait in own_hookbaits %}
{{ hookbait.name }}
{% endfor %}
{% endif %}
</ul>
</div>
views.py
class HookBaitUpdateView(UpdateView):
model = HookBait
template_name = "user_profile/hookbaits.html"
form_class = HookBaitForm
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['formset'] = HookBaitFormset(queryset=HookBait.objects.filter(fisherman=self.request.user.fisherman))
return context
def post(self, request, *args, **kwargs):
formset = HookBaitFormset(request.POST)
if formset.is_valid():
return self.form_valid(formset)
else:
return self.form_invalid(formset)
def form_valid(self, formset):
instances = formset.save(commit=False)
for instance in instances:
instance.fisherman = self.request.user.fisherman
instance.save()
return super().form_valid(formset)
def form_invalid(self, formset):
return HttpResponse("Invalid")
def get_success_url(self):
return reverse('user_profile:profile', args=(self.kwargs['pk'],))
urls.py
app_name = "user_profile"
urlpatterns = [
path("profile/<int:pk>/", views.ProfileView.as_view(), name="profile"),
path("profile/<int:pk>/hookbaits/", views.HookBaitUpdateView.as_view(), name="hookbaits"),
]
rendered html
<div class="row justify-content-center m-0">
<div class="col-12 col-md-6 col-lg-4 p-0">
<div class="row mx-3 my-3 justify-content-center text-center">
<div class="card p-2 custom-borders">
<div class="card-body p-2">
<form method="POST">
{% csrf_token %}
<table class="d-flex justify-content-center">
{{ formset.management_form }}
{% for form in formset %}
<tr class="formset_row">
{% for field in form.visible_fields %}
<td class="pb-2">
{% if form.instance.pk %}{{ form.DELETE }}{% endif %}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<input type="submit" class="btn btn-primary w-50 mt-1" style="background-color: #00754B;" value="Mentés">
</form>
</div>
</div>
</div>
</div>
</div>
Any suggestions what the solution would be? Thanks!
there are some possibilities
the wrong link clicked like if your trying access this URL profile/25/hookbaits/
and in the data index there is no HookBait with the id of 25
in HookBaitUpdateView you are trying to get queryset=HookBait.objects.filter(fisherman=self.request.user.fisherman)
maybe there is no hookbait associate with user.fisherman
404 page mostly served when you call get_object_or_404(HookBait, pk=25)
and update view may call this method

Django search pagination error, page not found error each time I try to move to page 2

I'm popping up with an error on my comic book ecommerce application. It's a Django app. Basically, the search function isn't paginating properly, giving me a page not found error each time I try to move to page 2 and onwards. It works fine in my general products listing area though, where there is no q-based search.
It works fine when I paginate just the products section, adding in...
paginate_by = 6
...into the class ListView section...
...and adding this section into the view.html section...
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
last »
{% endif %}
</span>
</div>
...But, once I try to paginate the search function in the same way, it appears to paginate, but page 2 and onwards just gives me a page not found error...
http://127.0.0.1:8000/search/?page=2
Request Method: GET
Request URL: http://127.0.0.1:8000/search/?page=2
Raised by: search.views.SearchProductView
....I think it has something to do with q, and the view.html section, but I'm not sure.
Any help would be much-appreciated.
Also, here's my view.html:
{% extends "base.html" %}
{% block content %}
<!-- <div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
last »
{% endif %}
</span>
</div> -->
<!--the heading with the result of the name-->
<div class="row mb-3">
{% if query %}
<div class="col-12">
Results for <b>{{ query }}</b>
<hr/>
</div>
{% else %}
<div class="col-12 col-md-8 mx-auto py-5">
{% include 'search/snippets/search-form.html' %}
</div>
<div class="col-12">
<hr>
</div>
{% endif %}
</div>
<!--create a card/item for each comic-->
<div class="row">
{% for obj in object_list %}
<div class="col">
{% include 'products/snippets/card.html' with instance=obj %}
{% if forloop.counter|divisibleby:3 %}
</div>
</div>
<!--or else if no item just create a blank row and column-->
<div class='row'><div class='col-12'><hr/></div>
{% else %}
</div>
{% endif %}
{% endfor %}
{% endblock %}
And here's a snippet that works within the view.html (search-form.html)
<form method="GET" action='{% url "search:query" %}' class="form my-2 my-lg-0 search-form">
<div class="input-group">
<input class="form-control" type="search" placeholder="Search" name='q' aria-label="Search" value='{{ request.GET.q }}'>
<span class='input-group-btn'>
<button class="btn btn-outline-success" type="submit">Search</button>
</span>
</div>
</form>
As well, here's my view.py backend:
from django.shortcuts import render
from django.views.generic import ListView
from products.models import Product
from django.core.paginator import Paginator
class SearchProductView(ListView):
#PROBLEM WITH PAGINATION IN THE SEarch function and view
#https://stackoverflow.com/questions/48436649/django-pagination-page-not-found?rq=1
#https://www.youtube.com/watch?v=acOktTcTVEQ
#https://www.youtube.com/watch?v=q-Pw7Le30qQ
#https://docs.djangoproject.com/en/3.1/topics/pagination/
#paginate_by = 6
template_name = "search/view.html"
def get_context_data(self, *args, **kwargs):
context = super(SearchProductView, self).get_context_data(*args, **kwargs)
context['query'] = self.request.GET.get('q')
return context
def get_queryset(self, *args, **kwargs):
request = self.request
method_dict = request.GET
query = method_dict.get('q', None) #method_dict['q']
if query is not None:
return Product.objects.search(query).order_by('title')
return Product.objects.filter(featured=True).order_by('title')
'''
__icontains = field contains this
__iexact = field is exactly this
'''
Finally, here are my urls:
from django.conf.urls import url
from .views import (
SearchProductView
)
urlpatterns = [
url(r'^$', SearchProductView.as_view(), name='query'),
]

How to fetch and display data from Django Model without invoking the URL

I have a Class-Based ListView as shown below:
class JobByStateView(ListView):
model = State
template_name = 'jobs/jobs_by_state.html'
context_object_name = 'state_list'
ordering = ['name']
paginate_by = 15
I have added the path to urls.py file as shown below:
path('jobs/', JobByStateView.as_view(), name='job-by-state'),
And this how my template looks:
<div class="row">
<div class="col-md-4">
<ul class="list-unstyled mb-0">
{% for state in state_list %}
{% if forloop.counter|divisibleby:"5" == False %}
<li>
{{state.name}}
</li>
{% else %}
<li>
{{state.name}}
</li>
</ul>
</div>
<div class="col-md-4">
<ul class="list-unstyled mb-0">
{% endif %}
{% endfor %}
</ul>
</div>
</div>
When I try to access this templates via the url (http://localhost:8000/jobs) it works as expected and displays the data on the screen. But when I try embed this template within another template as shown below, nothing gets displayed on the web page.
{% include 'jobs/jobs_by_state.html' %}
I would like to display this template as a widget within another template.
Really appreciate, if anyone could please help me in fixing this issue.
Thank you so much in advance for your time and help!
=========================================================================
The other page template is:
{% extends 'base.html' %}
{% block page_content %}
{% include 'carousel.html' %}
{% for job in job_list %}
<div class="listing-wrapper">
<div class="listing-container border-top border-bottom">
<a href="{{ job.get_absolute_url }}">
<h2 class="heading mt-3 mb-1 mx-2 d-inline-block">{{ job.title}}</h2>
</a>
</div>
</div>
{% endfor %}
{% if is_paginated %}
<ul class="pagination justify-content-center my-4">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link bg-dark text-white" href="?page{{page_obj.previous_page_number}}">← Previous Page</a>
</li>
{% endif %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link bg-dark text-white" href="?page{{page_obj.next_page_number}}">Next Page →</a>
</li>
{% endif %}
</ul>
{% endif %}
{% include 'jobs/jobs_by_state.html' with state_list=state_list %}
{% endblock page_content %}
{% block page_sidebar %}
{% include 'simple_search_widget.html' %}
<!-- Social Sharing Buttons -->
<div class="sharethis-inline-share-buttons mt-4"></div>
<!-- Newsletter Widget -->
{% include 'newsletter_widget.html' %}
{% endblock page_sidebar %}
The view for the parent template is as shown below:
class JobList(ListView):
model = Job
template_name = "jobs/job_listings.html"
context_object_name = "job_list"
ordering = ['-published_date']
paginate_by = 10
The following solution from #Charnel and #ChidG worked.
#Shahzan, ok, well you are referring to that variable in your template like this: {% include 'jobs/jobs_by_state.html' with state_list=state_list %}. So if the variable isn't in the context, it can't be passed to the included template, and so the included template won't display anything.

How to convert Generic Views to Class based Views for lists with modals

I'm trying to convert generic views to class based views, so that I can get some better readability in my code.
From this I want to be able to create a function so that I can show modals for individual items in a list. I'm new to django so I don't know what I can try, I've searched online and read the docs but not having any luck.
View I'm currently using:
def my_booking_list(request):
booking_lab = Reservation.objects.filter(username=request.user.username).order_by('-id')
key = settings.STRIPE_PUBLISHABLE_KEY
print(booking_lab)
return render(request, 'my_booking_list.html', {'booking_labs': booking_lab, 'key': key})
Class based view I have no idea what I'm doing with (am I at least on the right track?):
class MyBookingsView(ListView):
def get(self,request ,pk):
booking_lab = Reservation.objects.filter(username=request.user.username).order_by('-id')
key = settings.STRIPE_PUBLISHABLE_KEY
print(booking_lab)
return render(request, 'my_booking_list.html', {'booking_labs': booking_lab, 'key': key})
Template (partial):
{% if booking_labs %}
{% for lab in booking_labs %}
<div class="tg-dashboardservices">
<div class="tg-dashboardservice">
<div class="tg-servicetitle">
<h2>{{lab.lab.name}}
{% if lab.status == 'Accepted' %}
<span>({{lab.status}})</span>
{% elif lab.status == 'Requested' %}
<span>({{lab.status}})</span>
{% elif lab.status == 'Denied' %}
<span>({{lab.status}})</span>
{% endif %}</h2>
</div>
<div class="tg-btntimeedit">
<span>{{lab.price}}</span>
<button class="tg-btnedite"><a data-toggle="modal"
data-target=".tg-categoryModal">
<i class="lnr lnr-pencil"></i></a>
</button>
<button class="tg-btndel"><a><i class="lnr lnr-trash"></i></a>
</button>
</div>
</div>
</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{%for lab in booking_labs%}
<!--************************************
Theme Modal Box Start
*************************************-->
<div class="modal fade tg-invoicemodal tg-categoryModal" tabindex="-1">
<div class="modal-dialog tg-modaldialog" role="document">
<div class="modal-content tg-modalcontent">
<div class="tg-modalhead">
<h2>Details</h2>
<ul class="tg-btnaction">
<li class="tg-delete"><i class="lnr lnr-trash"></i></li>
</ul>
</div>
<div class="tg-modalbody">
<ul class="tg-invoicedetail">
<li><span>Lab Booked:</span><span>{{lab.lab.name}}</span></li>
<li><span>Company Name:</span><span>{{lab.lab.company}}</span></li>
<li><span>Amount:</span><span>${{lab.lab.price}}.00</span></li>
<li><span>Payment Method:</span><span>Stripe</span></li>
<li><span>Booking Status:</span>
{% if lab.status == 'Accepted' %}
<span>{{lab.status}}</span>
{% elif lab.status == 'Requested' %}
<span>{{lab.status}}</span>
{% elif lab.status == 'Denied' %}
<span>{{lab.status}}</span>
{% endif %}
</li>
<li><span>Booking Dates:</span>
<span>From: {{lab.CheckInDate}} {{lab.CheckInTime}} </br>
To: {{lab.CheckOutDate}} {{lab.CheckOutTime}}</span>
</li>
<li><span>Name:</span><span>{{lab.lab.contact_person}}</span></li>
<li>
<span>Address:</span><span>{{lab.lab.street_address}}, {{lab.lab.city}}, {{lab.lab.country}}</span>
</li>
<li><span>Message:</span><span>{{lab.message}}</span></li>
</ul>
</div>
</div>
</div>
</div>
{% endfor %}
<!--************************************
Theme Modal Box End
*************************************-->
{% endfor %}
{% endif %}
The code currently displays the modal 4 times, overlapping one another, I can click off of the modal to clear them, I know this is because of the for loop before the modal. I'm trying to achieve clicking on one item in a list to display its modal.
You can go through the django docs
In the list view just specify the model and paginate by count.
If you want to manually filter the queryset override the get_queryset() fun.
By default the context object name for the queryset will be object_list for a list view, So in the template loop over object_list. if you want to change it specify the context_object_name variable.