tags:

views:

204

answers:

1

I'm working on an image portfolio app, and I've got a url which looks like this:

url(r'^(?P<slug_val>[-\w]+)/(?P<page>[0-9]+)/(?P<id>[0-9]+)/$', 'portfolio.views.imagedetail')

Essentially, the page element is only there so I can nicely redirect the user back to the page of thumbnails they came from. However, if the URL gets passed around, and then some images get added or removed before the image, then it may no longer be on that page. I'd like to redirect users in that case to:

slug/correctpage/id

What I can't work out is how to work out what page an image is on, using Django's built-in pagination. Here's what I've got so far:

def imagedetail(request, slug_val, page, id):
    p = get_object_or_404(MyPortfolio, slug=slug_val)

    paginator = Paginator(p.images.all(), 25)

    # find out which page the image with id is on, if it's not page,
    # then redirect, otherwise render

I know I could iterate through each page, but that seems like it'll hit the database unnecessarily, and I'm sure there must be a more elegant way to do it.

Thanks,

Dom

+2  A: 

If you want to take into account database changes, you will have no other choice than querying the database or ... you must somewhere cache the changes in memory if you use just one web server. The latter is only an option if you don't have too many data or enough memory available.

The most elegant way to query something like the following, but this is something very difficult to achieve in Django 1.0 without using SQL:

SELECT COUNT(*) + 1 FROM images WHERE images.field < currentfield

(where field is the field of field you use for ordering your images)

To use raw SQL in Django, you can read this page for more information.

Then you know the position of your image, and you can easily calculate the page the item is in.

Michael
The development version of Django, and the 1.1 beta, support aggregate queries in ORM code, so you shouldn't need to drop back to raw SQL.
Daniel Roseman