Lookup across relations

1 view
Skip to first unread message

3xM

unread,
Feb 21, 2009, 2:27:42 PM2/21/09
to Django users
I've got 2 models:

----
class Person(models.Model):
...

class Project(models.Model):
...
persons = models.ManyToManyField(Person)
----

Now, how do I lookup Projects including person_a and person_b?

I've tried chaining filters like this, but that won't work (returning
no results):

Project.objects.filter(persons__id=person_a.id).filter
(persons__id.person_b.id)

Maybe I missed something, but I've read the documentation several
times now, without luck.

Do I have to write the SQL myself?

--

Best regards, Mikkel

Daniel Roseman

unread,
Feb 21, 2009, 4:33:14 PM2/21/09
to Django users
No need for custom SQL here. This might work:
Project.objects.filter(persons=person_a, persons=person_b)

Or you could probably do it with Q objects:
Project.objects.filter(Q(persons=person_a) & Q(persons=person_b))
--
DR.

3xM

unread,
Feb 22, 2009, 5:44:25 AM2/22/09
to Django users


On Feb 21, 10:33 pm, Daniel Roseman <roseman.dan...@googlemail.com>
wrote:

> No need for custom SQL here. This might work:
> Project.objects.filter(persons=person_a, persons=person_b)

Nope. It just returns projects including person_b.


> Or you could probably do it with Q objects:
> Project.objects.filter(Q(persons=person_a) & Q(persons=person_b))

Doesn't work either. This one returns no results, just like chaining
filters.

Any other suggestions? Does it work for you? Maybe I'm doing something
wrong?

--

Mikkel

Reza Muhammad

unread,
Feb 22, 2009, 10:56:49 AM2/22/09
to django...@googlegroups.com




On Feb 22, 2009, at 5:44 PM, 3xM <3...@detfalskested.dk> wrote:

>
>
>
> On Feb 21, 10:33 pm, Daniel Roseman <roseman.dan...@googlemail.com>
> wrote:
>
>> No need for custom SQL here. This might work:
>> Project.objects.filter(persons=person_a, persons=person_b)
>
> Nope. It just returns projects including person_b.
>
>
>> Or you could probably do it with Q objects:
>> Project.objects.filter(Q(persons=person_a) & Q(persons=person_b))
>
> Doesn't work either. This one returns no results, just like chaining
> filters.
>
I think the above was just a clue, if you need "OR" condition instead
of "AND", you need to use "|" not "&" so:

Project.objects.filter(Q(persons=persons_a) | Q(persons=persons_b))

Malcolm Tredinnick

unread,
Feb 22, 2009, 6:53:47 PM2/22/09
to django...@googlegroups.com
On Sun, 2009-02-22 at 22:56 +0700, Reza Muhammad wrote:

[...]


> > Doesn't work either. This one returns no results, just like chaining
> > filters.
> >
> I think the above was just a clue, if you need "OR" condition instead
> of "AND", you need to use "|" not "&" so:
>
> Project.objects.filter(Q(persons=persons_a) | Q(persons=persons_b))

If this is the case, then the original problem description was
incorrect.

Mikkel: you said you wanted projects containing person_a *and* person_b,
which is what the chaining filters and Q() & Q() version is giving you.
If they're returning no results, it's because no results exist.

The above filter -- Q() | Q() -- is going to return projects that
contain person_a *or* person_b. Is that what you're after?

Regards,
Malcolm


3xM

unread,
Mar 15, 2009, 9:52:31 AM3/15/09
to Django users
So, now I had the time to create at clean test case. it can be
downloaded here: <http://blackfin.cannedtuna.org/django-
testcase.tar.gz>

It contains a few views etc. to show the data in the database (in
sqlite3 format, also included in the .tar.gz).

Now, if I go into django's interactive shell (./manage.py shell) and
try out the above mentioned, using Q objects, I still get no results.
Could anybody please help me out, using my testcase? Am I doing
something wrong?

--

Best regards, Mikkel

3xM

unread,
Mar 15, 2009, 9:54:04 AM3/15/09
to Django users
Gees... It messed with my link. I'll try again:
http://blackfin.cannedtuna.org/django-testcase.tar.gz

Matías Costa

unread,
Mar 16, 2009, 6:47:12 AM3/16/09
to django...@googlegroups.com
On Sun, Mar 15, 2009 at 2:54 PM, 3xM <3...@detfalskested.dk> wrote:

Gees... It messed with my link. I'll try again:


It works OK here. I have added __rerpr__ method to models to get a clear output:

for p in Project.objects.all():
    print p.name, p.persons.all()
Corporate website [James, Sean, Jennifer]   
Customer x website [James, Jennifer]        
Customer y website [Sean, Jennifer]         

james = Person.objects.get(pk=1)

jennifer = Person.objects.get(pk=3)

Project.objects.filter(persons=james).filter(persons=jennifer)
[Corporate website, Customer x website]

Project.objects.filter(persons=james).filter(persons=jeniffer).query.as_sql()                                                                 
('SELECT "stuff_project"."id", "stuff_project"."name" FROM "stuff_project" INNER JOIN "stuff_project_persons" ON ("stuff_project"."id" = "stuff_project_persons"."project_id") INNER JOIN "stuff_project_persons" T4 ON ("stuff_project"."id" = T4."project_id") WHERE ("stuff_project_persons"."person_id" = %s  AND T4."person_id" = %s )',                                                                              
 (1, 3))

Matías Costa

unread,
Mar 16, 2009, 12:29:19 PM3/16/09
to django...@googlegroups.com
2009/3/16 Matías Costa <m.cos...@gmail.com>

On Sun, Mar 15, 2009 at 2:54 PM, 3xM <3...@detfalskested.dk> wrote:

Gees... It messed with my link. I'll try again:


It works OK here. I have added __rerpr__ method to models to get a clear output:
 
BTW,  this is Django 1.0, I had to rename your maxlength field parameter to max_length. Are you using 0.96?

Malcolm Tredinnick

unread,
Mar 16, 2009, 7:55:03 PM3/16/09
to django...@googlegroups.com
On Mon, 2009-03-16 at 17:29 +0100, Matías Costa wrote:
[...]

>
> BTW, this is Django 1.0, I had to rename your maxlength field
> parameter to max_length. Are you using 0.96?

Oh, dear. If the original poster is using 0.96, then this has little
chance of working. Complex queries involving many-to-many objects didn't
work well there at all. It was an area of many bugfixes between 0.96 and
1.0.

Regards,
Malcolm

>

3xM

unread,
Mar 17, 2009, 4:28:58 PM3/17/09
to Django users
On Mar 16, 5:29 pm, Matías Costa <m.costac...@gmail.com> wrote:

> BTW,  this is Django 1.0, I had to rename your maxlength field parameter to
> max_length. Are you using 0.96?

Yes I am... 0.96 is what comes with Ubuntu 8.04 LTS.

I'll upgrade to Ubuntu 8.10 (with django 1.0) as soon as possible and
get back to tell if solved the problem.

Sorry for wasting your time if this is what is wrong.

--

Mikkel

Matías Costa

unread,
Mar 18, 2009, 3:00:50 AM3/18/09
to django...@googlegroups.com
On Tue, Mar 17, 2009 at 9:28 PM, 3xM <3...@detfalskested.dk> wrote:
I'll upgrade to Ubuntu 8.10 (with django 1.0) as soon as possible and
get back to tell if solved the problem.

I imagine you can upgrade django without upgrade the whole OS. Try to uninstall 0.96 (apt-get), download 1.1 and untar it directly under your project folder. It should work.


Sorry for wasting your time if this is what is wrong.

You're welcome.

Malcolm Tredinnick

unread,
Mar 18, 2009, 3:03:20 AM3/18/09
to django...@googlegroups.com
On Wed, 2009-03-18 at 08:00 +0100, Matías Costa wrote:
> On Tue, Mar 17, 2009 at 9:28 PM, 3xM <3...@detfalskested.dk> wrote:
> I'll upgrade to Ubuntu 8.10 (with django 1.0) as soon as
> possible and
> get back to tell if solved the problem.
>
>
> I imagine you can upgrade django without upgrade the whole OS. Try to
> uninstall 0.96 (apt-get), download 1.1

Um ... 1.1 doesn't exist yet. All the necessary query improvements are
in 1.0.2, though. So that's the point to aim for.

Regards,
Malcolm

>

Brett Parker

unread,
Mar 18, 2009, 12:02:28 PM3/18/09
to django...@googlegroups.com

At which point, he can probably just install the .deb from the debian
lenny repository (Chris Lamb has been really on the ball in getting the
releases through recently, and many thanks to him!).

http://packages.debian.org/lenny/all/python-django/download

Cheers,
--
Brett Parker

3xM

unread,
Mar 25, 2009, 5:13:37 AM3/25/09
to Django users
An upgrade to Ubuntu 8.10 with Django 1.0 solved the problem. Thanks
for all your help.
Reply all
Reply to author
Forward
0 new messages