On Mon, 2009-05-04 at 09:18 -0700, Riccardo Pelizzi wrote:
> Hello,
> 
> I have a model which looks kinda like this:
> 
> class Host(model):
>   ip = IPAddressField()
> 
> class Domain(model):
>   hosts = ManyToManyField(Host)
> 
> If i want to get all the domains without hosts:
> Domain.objects.filter(hosts=None)
> works.
> 
> Later on in my script i need to get the opposite, all the domains
> having one or more hosts associated. using exclude instead of filter
> with the same condition doesn't work as expected (at least as I
> expected :-P), it just returns an empty queryset. Is there a way to
> formulate the query using the django api? or should i use custom sql?

That should work properly. It works for me using exactly your models
with a few different Host/Domain combinations.

The SQL we currently generate for Domain.objects.exclude(hosts=None) is
a little inefficient, but it's not fundamentally incorrect. It just uses
a couple more tables than it needs to be because the "NULL" case can
take advantage of one particular extra optimisation that isn't in the
code yet. I'm surprised it isn't returning the correct result.

Another to get the same answer, which generates simpler SQL but is
potentially a little less efficient on the database side is

        Domain.objects.filter(hosts__isnull=False).distinct()
        
That's essentially the only case where Django has a "not" filter
available: you can actually filter for "not NULL". The distinct() call
there is important, as for many-to-many fields, you would otherwise get
back one domain object for every host (so repetitions for domains with
multiple hosts), not just the set of domains that have at least one
host.

In any case, I suspect there's something else going on in your
particular case, as the SQL generated should be pulling back the results
you're after and it works with a small example using your models. If you
can use those models, as pasted, to generate an incorrect result, what
is the smallest amount of data (Host & Domain objects) you need to
create to demonstrate the problem. That would be interesting to see.

Regards,
Malcolm


--~--~---------~--~----~------------~-------~--~----~
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