More complex QuerySets and generic views

25 views
Skip to first unread message

Jon Atkinson

unread,
Aug 15, 2006, 1:52:41 PM8/15/06
to django...@googlegroups.com
Hi,

I'm dabbling with generic views (thanks to wise advice from others on
this list), and I'm trying to convert one of my slightly more
complicated views to use a generic view. The vie itself is a simple
list, but my queryset is generated as follows:

Item.objects.filter(feed__feedtype__feedtype__iexact=re.sub('(s$|S$)',
'', feedtype)).order_by('-time')

What I'm trying to achieve here is not locking users into a certain
URL scheme - for the feedtype, I want uses to be able to specify
'/link', '/links', '/LINKS', and any combination thereof, hence the
regular expression which removes the trailing 's' from the request and
performs the case-insensitive query. This works fine when I use it in
a traditional view.

Now that I'm trying to use generic views (to avoid doing some ugly
pagination by hand), my urls.py line is as follows:

(r'^/?(?P<feedtype>\w+)/$',
'django.views.generic.list_detail.object_list', {'queryset':
Item.objects.filter(feed__feedtype__feedtype__iexact=re.sub('(s$|S$)',
'', feedtype)).order_by('-time'), 'paginate_by': 15, 'extra_context':
{'is_first_page': True}}),

However, the error which I get is as follows:

NameError at /photo/
name 'feedtype' is not defined
Request Method: GET
Request URL: http://localhost:8000/photo/
Exception Type: NameError
Exception Value: name 'feedtype' is not defined

I'm guessing that this is being caused by the regular expression
evaluation not seeing that 'feedtype' exists - is there a way to solve
this or will I have to use a standard view for this particular action?

--Jon

Chris Long

unread,
Aug 15, 2006, 2:45:55 PM8/15/06
to Django users
You could simplify your urls.py by extending the generic view with
another view, e.g. an example from the authorization document:

from django.views.generic.date_based import object_detail

@login_required
def limited_object_detail(*args, **kwargs):
return object_detail(*args, **kwargs)

It might also help with the problem you are having.

Chris

Michael van der Westhuizen

unread,
Aug 15, 2006, 3:11:36 PM8/15/06
to django...@googlegroups.com
Hi Jon,

Do you really need the RE in the query? I think the problem is that
the re call is being evaluated immediately, which the query is lazily
evaluated. Would the "iexact" not work without the regular expression?

If you do end up needing the RE, you could try using a custom manager
on your feeds model. Specifically, you could create a custom manager
method which filters based on the regular expression, then pass that
the captured feedtype from the URL.

See http://www.djangoproject.com/documentation/model_api/#managers for
details of custom managers and adding methods to them.

Michael

Jon Atkinson

unread,
Aug 15, 2006, 4:17:57 PM8/15/06
to django...@googlegroups.com
On 15/08/06, Michael van der Westhuizen <r1m...@gmail.com> wrote:
>
> Do you really need the RE in the query? I think the problem is that
> the re call is being evaluated immediately, which the query is lazily
> evaluated. Would the "iexact" not work without the regular expression?
>
> If you do end up needing the RE, you could try using a custom manager
> on your feeds model. Specifically, you could create a custom manager
> method which filters based on the regular expression, then pass that
> the captured feedtype from the URL.
>
> See http://www.djangoproject.com/documentation/model_api/#managers for
> details of custom managers and adding methods to them.
>
> Michael

I've just tried removing the regular expression - so the line looks like:

(r'^/?(?P<feedtype>\w+)/$',
'django.views.generic.list_detail.object_list', {'queryset':

Item.objects.filter(feed__feedtype__feedtype__iexact=feedtype).order_by('-time'),


'paginate_by': 15, 'extra_context': {'is_first_page': True}}),

And oddly enough I'm getting exactly the same error; is there another
problem with this statement which I'm not seeing? It seems there is a
problem with variable from the url expression being passed to the view
function - is this a common problem?

--Jon

Michael van der Westhuizen

unread,
Aug 15, 2006, 5:03:37 PM8/15/06
to django...@googlegroups.com
Hi Jon,

On 8/15/06, Jon Atkinson <j...@jonatkinson.org> wrote:

[snip]


> I've just tried removing the regular expression - so the line looks like:
>
> (r'^/?(?P<feedtype>\w+)/$',
> 'django.views.generic.list_detail.object_list', {'queryset':
> Item.objects.filter(feed__feedtype__feedtype__iexact=feedtype).order_by('-time'),
> 'paginate_by': 15, 'extra_context': {'is_first_page': True}}),
>
> And oddly enough I'm getting exactly the same error; is there another
> problem with this statement which I'm not seeing? It seems there is a
> problem with variable from the url expression being passed to the view
> function - is this a common problem?

I think you've just identified the problem! Unfortunately, this means
that you're going to need a custom view for this object list.

What's lacking in the generic object list is a "slugfield" similar to
what's found in generic object detail. If that existed, you'd be able
to do something like this:

(r'^/?(?P<filter>\w+)/$',
'django.views.generic.list_detail.object_list',
{'queryset': Item.objects.all().order_by('-time'),
'filter_field':'feed__feedtype__feedtype__iexact',
'paginate_by': 15 }),

Django would then substitute the captured "filter" variable into the
query-set like this:

Item.objects.all().order_by('-time').filter(
feed__feedtype__feedtype__iexact = captured_value )

I think it's worth raising a feature request in the Django Trac for
this functionality. I can imagine that this would be very useful to a
lot of people in the future.

Michael

Adrian Holovaty

unread,
Aug 15, 2006, 6:04:39 PM8/15/06
to django...@googlegroups.com
On 8/15/06, Jon Atkinson <j...@jonatkinson.org> wrote:
> (r'^/?(?P<feedtype>\w+)/$',
> 'django.views.generic.list_detail.object_list', {'queryset':
> Item.objects.filter(feed__feedtype__feedtype__iexact=feedtype).order_by('-time'),
> 'paginate_by': 15, 'extra_context': {'is_first_page': True}}),
>
> And oddly enough I'm getting exactly the same error; is there another
> problem with this statement which I'm not seeing? It seems there is a
> problem with variable from the url expression being passed to the view
> function - is this a common problem?

You're using a variable "feedtype" that's not defined.

It's the same thing as doing this in the Python interactive prompt:

print a + 1

The variable "a" is not defined yet, so Python raises a NameError.

The problem in your case is that your view won't know the value of
feedtype until the URL is parsed. For that reason, you cannot put that
logic in the URLconf.

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com

Jon Atkinson

unread,
Aug 15, 2006, 6:17:07 PM8/15/06
to django...@googlegroups.com
>
> I think it's worth raising a feature request in the Django Trac for
> this functionality. I can imagine that this would be very useful to a
> lot of people in the future.
>
> Michael

Done!

http://code.djangoproject.com/ticket/2544

--Jon

Jon Atkinson

unread,
Aug 15, 2006, 6:20:56 PM8/15/06
to django...@googlegroups.com
> You're using a variable "feedtype" that's not defined.
>
> It's the same thing as doing this in the Python interactive prompt:
>
> print a + 1
>
> The variable "a" is not defined yet, so Python raises a NameError.
>
> The problem in your case is that your view won't know the value of
> feedtype until the URL is parsed. For that reason, you cannot put that
> logic in the URLconf.
>
> Adrian
>
> --
> Adrian Holovaty
> holovaty.com | djangoproject.com
>

Adrian,

I've just read your reply _after_ I submitted the ticket - please do
close it if necessary.

Just out of interest, what do you think the most elegant way to solve
this problem would be? Is it to write my own view and deal with the
pagination myself?

Many thanks to all who replied to this thread.

--Jon

Reply all
Reply to author
Forward
0 new messages