Pagination with function based view with dictionary - python

I'm trying to paginate the pages with the help of Paginator. Have written this so far but I don't understand what would I pass in the context. Simply doing this doesn't work, I think my knowledge with Paginator is limited.
customerproducts = customerproductsjsondata.json()
customerproducts_list = customerproducts['data']
paginated_products = Paginator(customerproducts_list, 20)

You may want to return multiple things, like queryset for the current page, current page number, whether there is prev or next page, number of total records, number of total pages based on the offset.
You need to get the page from Paginator depending on the page number:
page_number = request.data.get('page_num')
page = paginated_products.page(page_number)
total_records = paginated_products.count
total_pages = paginated_products.num_pages
queryset = page.object_list
has_prev = page.has_previous()
has_next = page.has_next()
but you can User DRF's included pagination support by following the link https://www.django-rest-framework.org/api-guide/pagination/

Related

How do I preserve search result in Django pagination

I am new to Django and I have develop form with Country and State field from the Profile Model. If I search for country and a particular state, I want a list of persons belonging to that country and state to display and paginated. And if the records are in multiple pages then I should be able to click on individual pages that follow to view the searched results on those pages without losing the search results.
Here is my views code with pagination.
def search_applicants(request):
form = ApplicantsSearchForm(request.GET or None)
if form.is_valid():
list_submited = Profile.objects.filter(
nation__icontains=form.cleaned_data['nation'],
state__icontains=form.cleaned_data['state']
)
else:
list_submited = submited_apps.objects.all()
paginator = Paginator(list_submited, 5)
page = request.GET.get('page')
paged_listApps = paginator.get_page(page)
context = {
'list_applicants':paged_listApps,
'form':form,
}
return render(request, 'user/list_applicants.html',context)
I have got the pagination of all records from the Profile Model but any time I perform a search and try to click on the pagination tabs the search result is get scattered and returns to all the list items in the database.
On the front-end you need to submit your search data when clicking on your pagination tabs as well.

django paginationated first page content different to root page content (with cache)

I am paginating content based on a random queryset and I seem to be getting inconsistent results between the paginated first page ?page=1 and the root page itself.
So, I have my ListView like so:
class Some1_ListView(ListView):
model = Some_Model
template_name = "test1.html"
paginate_by = 12
context_object_name = "test1"
queryset = Some_Model.objects.all().order_by('?')[:24]
My urls is like so:
urlpatterns = [
path('test1/', cache_page(500)(Some1_ListView.as_view()), name="test1" ),
]
and the template is paginated according to the django docs, nothing special. Now, when I go to:
localhost/test1
I get the first 12 objects. Now, When I move to the next page, onbiously, my url becomes:
localhost/test1/?page=2
This renders fine aswell. Now, when I go back to
localhost/test1/?page=1
I see that the results are not the same as localhost/test1/
So, localhost/test1/?page=1 != localhost/test1/ Since I was caching the URL, I was expecting these two to be the same.
Can someone enlighten me as to why this is? and how do I get aorund it? Id like both these pages to show the same content (from cache).

How do i correctly implement web scraping into my api

I'm making a django api that is able to return a definition of a word to a user this word is looked up by using a word=(put word here) url, this api scrapes dictionary.com to get the definition if it does not already exist inside my database, than adds it to my database if it exists on their site. i'm just trying to figure out how to actually structure it correctly instead of just throwing it into my view. I want to be able to return json to the end user with suggestions if a word is not found in the database or on their websites by scraping their recommendations.
I have tried returning json responses inside the view if a 404 error happens. Always throws a error i'm under the assumption my whole structure is wrong.
# the queryset for a view
def get_queryset(self):
# this gets the word put into the url
word = self.kwargs['word']
headers = {"User-Agent": "user agent stuff"}
# this checks if it exists in the database
if not Word.objects.filter(word=word).exists():
#this is the web scraping
page = requests.get(f"https://www.dictionary.com/browse/{word}?s=t", headers=headers)
soup = BeautifulSoup(page.content, 'html.parser')
try:
output = soup.find("div",{"value": "1"}).get_text()
# this saves the web scraped info to the database
test = Word(word=self.kwargs['word'].strip(), meaning=output)
test.save()
except:
return
# this returns the word and definition
return Word.objects.all()
i expect the user to be able to get a definition if the word exists or if it doesn't to be able to return recommendations that i web scrape for them to choose from.
get_queryset is probably not the right place to put your scraping logic. Instead you want to use the default query set for your model to see if you have a definition, if not then perform the query to the 3rd party api, store the response into your database and return the definition to the user.
Outline
class WordViewSet(viewsets.ModelViewSet):
queryset = Word.objects.all()
serializer_class = WordSerializer
def retrieve(self, request, pk=None):
word = Word.objects.find(id=pk)
if not word:
# query 3rd party api
res = requests.get('dictionary.com', params={'q': request.param['word']})
word = res.json()['definition']
word = Word('title': ..., 'definition': ...)
word.save()
serializer = WordSerializer(word)
return Response(serializer.data)

Passing variables from Jinja to database

I'm trying to figure out a way to pass a dynamic URL with webpy that will render a Jinja template with information about the information that was passed. Specifically I have a item database that should be able to take whatever item ID is in the URL and render a template with further information about that item.
To simply the problem, I've hardcoded the value 1043374545 for demonstrations purposes, but I'm hoping that this line will be come dynamic once this initial problem is solved.
urls = ('/1043374545', 'view_item')
class view_item:
def GET(self, itemID):
item_info = sqlitedb.detailInfo(request)
return render_template('view_item.html', item = item_info)
As of now I isolated the issue to having to do with something related to passing the value 1043374545 into the view_item function. Any thoughts on how I can pass a dynamic number within a URL into view_item?
simply put:
urls = (('/([0-9]*)', 'view_item'),)
[0-9]* will tell webpy to only accept numbers after the "/".
Then you can use that value in your GET function, it will be under itemID as you specified in your GET parameter.
class view_item:
def GET(self, itemID):
item_info = sqlitedb.detailInfo(itemID)
return render_template('view_item.html', item = item_info)
check this link for more details:
http://webpy.org/cookbook/url_handling

Change number of items per page or view all in a view using a paginator in django

I am using django 1.3 and I have a view that takes a paginated queryset (set to use 50 objects). Here is the relevant part of the get_context_data() method in the view:
#build paginator for querysets
paginated_scanned_assets = Paginator(scanned_assets_qs, 50)
#get the specified page
try:
page_num = int(self.request.GET.get('page', '1'))
except ValueError:
page_num = 1
#get a paginated list of object
try:
scanned_assets = paginated_scanned_assets.page(page_num)
except (EmptyPage, InvalidPage):
scanned_assets = paginated_scanned_assets.page(paginated_scanned_assets.num_pages)
The template it renders to just builds a table from the queryset and has links to go to the next and previous pages.
What I want to do is either have a link to view all, which would just display the queryset unpaginated, or an option to modify the number of objects per page (which would recreate the paginator). I haven't worked with views or design much though so I am not sure how to do this. Is it something I can do with js, and if so how? Otherwise can I just do it with django and html? It might be really simple, I am just pretty inexperienced and haven't found an answer or example anywhere.
Thanks!
What you want to do is add an optional parameter to the view called 'page_size' and then do something like:
def your_view(request, ..., page_size=50):
scanned_assets_qs = # get your scanned_assets QuerySet
if page_size == -1:
page_size = scanned_assets_qs.count()
paginator = Paginator(scanned_assets_qs, page_size)
Then you can pass in an arbitrary page_size, and a -1 for a view all page (I would do that with the appropriate urls, plus a url for /viewall/ that passes in -1 no matter what)

Categories