I am creating a library management system using django, HTMX, HTML and CSS
There is admin panel. In admin panel, admin can manage books and other things. Admin can search through different things- books, members, authors.
When using Pagination, when does the db exactly get a hit.
From what I know, django creates lazy sql and is executed when value is actually used. (don’t know properly.). Please enlighten me.
I am worried about performance and correct implementation of process with paginator.
what I am doing rn now is:
admin open manage books »»
Process:
- system fetch all books {booksObj = models.Books.objects.all() }
- Then booksObj is passed through paginator to divide content into pages
- then page number is given to get_pages() to extract list of item from a particular page.
so everytime I click on next page, the above process is repeated. Is this normal process or am doing something wrong leading to repeatition of certain things.
Welcome @manindersingh-41dev !
First, keep in mind that there is no persistence of information between requests (other than what you might manage yourself). This means that whatever data you retrieve in your first request is not available for the second or any subsequent request. There is no built-in way to track what page you’ve previously retrieved, or what data was retrieved for that page.
What actually happens (when you use the Django Paginator class) is that Django doesn’t actually retrieve the full set of all objects. The queryset is defined for .all(), but the queryset isn’t resolved right away. (As you mentioned, querysets are lazy.) When you pass a page number to retrieve, the Paginator class augments the queryset by restricting the query for the list of elements needed for that page, and so it is only resolved for those elements. (See the code in django.core.paginator.Paginator)
Thanks @KenWhitesell for replying….
So you mean the process is quite normal and won’t stress the server by hitting the process again and again.
Like If I search for some book:ABC. There are many books that resemble the name ABC like ABC def, new era of ABC and so on. Then process would be :
- system create query for book__icontains=’ABC’ – lazy Query
- obj sent to Paginator class with objects – lazy Query
- page is fetched using obj.get_page(num) – lazy Query
In HTML:
values are displayed…
{% for book in books_page %} — Database gets a hit and fetch all object with name ABC for page 2
I hope I am right. Would this be the correct way of fetching things.
Correct.
You are, and yes it is.
The query that would actually be issued for page 3 with 10 items per page would be something like:
SELECT bk_book.id, bk_book.title, bk_book.year FROM bk_book
WHERE UPPER(bk_book.title) LIKE UPPER('%ABC%') LIMIT 10 OFFSET 20
Thanks bro for the reply…
I am stuck with another thing. Here is scenario:
There is search bar on Manage books page. This search bar is being used to fetch books only (that is managed is views by checking where is it being issued). After searching the results are swapped in the HTML code of table. Full page is not refreshed. HTML for table is stored in file named bookList_Partials.html
The searched items are also paginated. The next button which is inside the partial file div contains hx-get request for fetching next page content.
The problem arises when i searched something, it gave me result. when I click next page, the url containing search query gets reset. The url now contains number of next page.
If I hardcode url (as I have done hx-get=“{% url ‘library:AllBooks’ %}?page={{pageNum}}” ), then I am not able to paginate for going on page2 of search results. It shift to page 2 of normal list.
I hope you are able to understand the workflow I am trying to create. How can I achive following:
- Opening manage book opens the list of all books.
On clicking next-page, it goes to next page of all books (its done with hx-get)
- Searching will through books and display list of books that matches the query.
On clicking next-page, it goes to next page of search results.
- removing all the search keywords, would shift to point 1.
Note: All above is being done in div containing table of list of books.
I have in mind the solution using some flags and then doing the if-else work. But this approach seems too dirty to follow. Is there any other way achieving above.
Thanks
What you need to do in your template is include the search criteria in the url being constructed here. Then have your view render the search value in the template.
If I do that, how do I render the normal list of books. Should I be creating two different partial templates one with url of search and other one normal like the above??
Speaking in general terms, it would be done with only applying the filter to the query and rendering those search terms in the template if there are search terms involved.
I wouldn’t be able to be more specific without seeing the complete code involved. This would include the model(s), view(s), forms (for the search), and templates.
Let me put code on github and I will share the link here.
@KenWhitesell
Here is the code: GitHub - manindersingh-41dev/libraryManagement
The code is little messy being the first django project.
Which view, form and templates should I be focused on?
library/views.py : Admin methods starts after line 251. Particularly adminAllBooksView [line:286] and adminSearchView [Line 318]
Templates: library/templates/library/admin/admin_AllBooks.html and ibrary/templates/library/admin/partials/bookList_table.html
Also If you look at templates, you will see {%csrf_token%} in them without any form. I hope thats correct as it was needed to send a hx-request.
Thanks a lot for help…
1 Like
Hey @KenWhitesell , I have prepared the solution. I am sending custom url from view which solved the problem. Things are working now. Although I see a thing with url.
The URL in the urlBox seems okay. It doesn’t change.
But url at backend does change…
When open books initially : /library/admin/books/
Navigation initially: /library/admin/books/?page=2
When searched : /library/admin/books/search/?searchBook=tes
Navigation with search : /library/admin/books/search/?searchBook=tes&page=2
when search is cleared : /library/admin/books/search/?searchBook=
Navigation after clearing search: /library/admin/books/search/?searchBook=&page=2
Do you see something suspicious or problematic here.
These URLs are in backend only and are not visible to user. User see only : /library/admin/books/
I do not. Are you having a problem with this?
This would be correct. The address bar is not changed by AJAX-style requests.
No I have no problem with this.
Thanks a lot for helping out.