I am trying to figure out how to do isnull lookups with the admin
change list filter.  I am using the django master branch (off of
github), updated to 4/28.

I have a couple models with a simple relation:

from django.db import models

class ModelOne(models.Model):
  pass

class ModelTwo(models.Model):
  one = models.ForeignKey(ModelOne)

I can filter on `two_set__isnull=True` to find ModelOne not referenced
by any ModelTwo and `two_set__isnull=False` to find ModelOne that is
referenced by any ModelTwo.  That works well enough in python.

I can't find a way to do this with the admin change list filter.  The
ChangeList class does recognize and accept querystrings like the
following:

/admin/foo/modelone/?two_set__isnull=True
/admin/foo/modelone/?two_set__isnull=
/admin/foo/modelone/?two_set__isnull

The problem is that the parameters are all strings.  It seems the
behavior of isnull lookups is not useful for non boolean values.
Perhaps that is sensible.

I have a couple ideas toward making this work.

One idea involves the ChangeList class that does the work of
converting the request.GET parameters to a QuerySet.  This could do
the conversion to a boolean value.  There is presently a branch to
specially handle in lookups there.

My other idea is to make isnull lookups work for non-boolean types.
This is actually already done to generate the IS NULL / IS NOT NULL
sql, but there is also a test to change the join type so NULL values
or returned for rows where the join fails (instead of no row).

Is this an issue for anyone else?  Am I barking up the wrong tree?
I'm fairly new to django, so I could just be missing something here.


Kai


Patch to make the admin ChangeList class coerce isnull lookups to use
bool.
--- a/django/contrib/admin/views/main.py
+++ b/django/contrib/admin/views/main.py
@@ -185,6 +185,10 @@ class ChangeList(object):
             if key.endswith('__in'):
                 lookup_params[key] = value.split(',')

+           # if key ends with __isnull, convert the value to a boolean
+           elif key.endswith('__isnull'):
+               lookup_params[key] = bool(value)
+
         # Apply lookup parameters from the query string.
         try:
             qs = qs.filter(**lookup_params)


Patch to make BaseQuery use a more relaxed test for truthiness.
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1536,7 +1536,7 @@ class BaseQuery(object):
                     can_reuse)
             return

-        if (lookup_type == 'isnull' and value is True and not negate
and
+        if (lookup_type == 'isnull' and value and not negate and
                 len(join_list) > 1):
             # If the comparison is against NULL, we may need to use
some left
             # outer joins when creating the join chain. This is only
done when


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to