Get records before and after current selection in Django query

It sounds strange, but it's a very simple idea. I am trying to make a simple Flickr for a website I am building. This particular problem occurs when I want to show one photo (from my model Photo

) on the page, but I also want to show the image in front of it in the stream and the image after it.

If I were only sorting these streams by date, or just sorting by ID, it might be easier ... But I am not. I want to allow the user to sort and filter using a variety of methods. Sorting is simple. I did this and I have a result set containing 0-many Photo

s.

If I want one Photo

, I start with this filtered / sorted / etc stream. From it I need to get the current one Photo

, Photo

before and Photo

after it.

This is what I see now.

prev = None
next = None
photo = None

for i in range(1, filtered_queryset.count()):
    if filtered_queryset[i].pk = desired_pk:
        if i>1: prev = filtered_queryset[i-1]
        if i<filtered_queryset.count(): next = filtered_queryset[i+1]
        photo = filtered_queryset[i]
        break

      

It just seems disgustingly dirty. And ineffective. Oh my lord, so ineffective. Can anyone improve it though?

Django requests are late bindings, so it would be nice to use that, although I guess it might not be possible given my terrible limitations.

Edit: It occurs to me that I might just loop over some SQL queries to re-filter the queries. If there is a way to select something with two (or one or zero) nearest neighbors with SQL, I'd love to know!

+2


source to share


2 answers


You can try this:



  • Evaluate the filtered / sorted query and get a list of the photo IDs you are holding in the session. These IDs meet the filter / sort criteria.
  • Keep the current index in this list and in the session, and update it when the user moves to the previous / next photo. Use this index to use prev / current / next readings for displaying photos.
  • When the filtering / sorting criteria change, redefine the list and set the current index to an appropriate value (for example, 0 for the first photo in the new list).
+1


source


I see the following possibilities:

  • Your url query parameters contain sorting / filtering information and some sort of "position number" which is the position number within your filtered query. This is a simple case - previous and next - position number minus one plus plus one (plus some bounds checks)

  • You want the URL to be persistent and contains the photo's primary key (or unique identifier). In this case, you are apparently keeping the sort / filtering in:

    • in the URL as query parameters. In this case, you have no real permalinks, so you can also insert the position number into the URL, returning you to option 1.
    • hidden fields on the page and using POST for links instead of regular links. In this case, also insert the item number in the hidden fields.
    • session data / cookies. This will break if the user has two open tabs with different types / filtering, but that might be a limitation that you don't mind. After all, you guessed that they would probably just use one tab and click through the list. In this case, store the item number in the session. You might be able to do something clever for the "namespace" for the item number for the case when they have multiple tabs open.


In short, save the position number wherever you snore your filtering / sorting information.

+1


source







All Articles