1

In this Django app of mine, I use a ListView class to list user-uploaded photos. One can upvote or downvote these photos. Non-authenticated users can see the photos, but not allowed to cast votes.

An unignorable section of my users use legacy devices that can't support JS. For such users, upvote or downvote isn't AJAX-enabled. Instead, the entire page refreshes.

I ensure the page refresh still lands such users on the same photo they voted. I do this via the <a name="section{{ forloop_counter }}"> tag in HTML.

I show 20 photos per page, i.e. 20 sections. Upon voting, I pass the photo_id to def get(self, request, *args, **kwargs) method of ListView class. I calculate which section_num the photo_id appears in. Then I simply do return HttpResponseRedirect(section_num). This lands me at the correct position, e.g. http://example.com/?page=1#section8.

My question is: instead of using a ListView class, assume I'm writing my own custom view to list out the photos and such. How do I implement the aforementioned HttpResponseRedirect(section_num) functionality in this case? An illustrative example would be great. Thanks in advance!


Here's my custom view:

    def photos_list(request, *args, **kwargs):
        form = PhotosListForm()
        ob_list = retrieve_latest_photos(request.user.id)
        paginator = Paginator(ob_list, 20)
        page = request.GET.get('page', '1')
        try:
            page = paginator.page(page)
        except PageNotAnInteger:
            page = paginator.page(1)
        except EmptyPage:
            page = paginator.page(paginator.num_pages)
        context = {'object_list': ob_list, 'form':form, 'page':page,'username':request.user.username}
        return render(request, 'photos_list.html', context)

Note: I read this SO question, but can't discern how it helps in my case. Part of that is because I'm a beginner, but also because the op there seems to have a different problem

Community
  • 1
  • 1
Hassan Baig
  • 15,055
  • 27
  • 102
  • 205

1 Answers1

0

Your questions is not clear - however, did you consider using <a name="section{{ object.id }}"> or <div id="photo-{{ object.id }}"> and redirect to the #photo.id instead of calculating?

Udi
  • 29,222
  • 9
  • 96
  • 129
  • Udi, thanks for the tip. My question is this: I have to pass a `context` dictionary to the template, thus I'm using `render()` in my **custom view**. Now what would I need to do to redirect to a specific anchor tag within the page? With a ListView class, I can use `HttpResponseRedirect` in the `get()` method. What about when using a custom view? – Hassan Baig Dec 25 '16 at 11:54
  • Yes, you can use it from a custom view. – Udi Dec 25 '16 at 12:20
  • Okay, got it. Basically `vote` will call a custom redirect view, which uses `HttpResponseRedirect` to get to the correct anchor tag. As for the tip regarding using `object.id` - I didn't explain it clearly enough - I need to deduce the **page number** as well since the photos list is paginated. I.e. calculate `?page=1#section8` and not just `#section8`. How do I do that if I use your tip in the answer? – Hassan Baig Dec 25 '16 at 19:37
  • Good question. There are a few options. An optimistic one is to remember the page number before the operation and display it again. I would choose this. If you know the sort order, you can count the items appearing before the item and divide it by page size. – Udi Dec 25 '16 at 19:56