On Wed, Apr 28, 2010 at 5:12 PM, HWM-Rocker <olafgla...@gmail.com> wrote:
>
>
> On Apr 28, 4:21 am, Tom Evans <tevans...@googlemail.com> wrote:
>> On Wed, Apr 28, 2010 at 1:00 AM, HWM-Rocker <olafgla...@gmail.com> wrote:
>> > I have a TaggedObject that has a GenericRelation to Foo with the name
>> > tags. When I am searching something like that
>>
>> > TaggedObject.objects.filter(Q(tags__tag=1)&Q(tags__tag=4))
>>
>> > I get no Objects in return. But when I filter with (or) '|' then I get
>> > 4 Objects. But I have only 3 objects tagged. So the object, that was
>> > tagged with 1 and with 4 will be returned twice?
>>
>> > Thats strange. Any idea how to create this queries correctly?
>>
>> > thanks in advance!!!
>>
>> That query looks for tags which are both 1 and 4 at the same time.
>> What you want to do is look for tags which are 1, look for tags which
>> are 4, and intersect them.
>>
>> In other words:
>>
>> TaggedObject.objects.filter(tags__tag=1).filter(tags__tag=4)
>
> yeah I changed my code, but is there any possibility to do this with
> Q, so that I can just execute one query in the end? I want to build a
> complex nested search/filter and Q gives me the possibility to negate
> queries. Is there a possibility to split those two Q's to behave in a
> way that would be useful for my case.
>
>>
>> Cheers
>>
>> Tom
>>
> thx for your tip !!

What you ask the ORM for has more effect on how many queries are done
than how many times you call filter() - querysets are only evaluated
(go to the DB) when they are displayed/iterated through.

This ORM statement:
  TaggedObject.objects.filter(tags__tag=1).filter(tags__tag=4)

would boil down to one SQL statement, joining to the tags table twice.

Use the django debug toolbar, or manually examine
django.db.connection.queries ("from django.db import connection; print
connection.queries") to see more clearly what the ORM is doing.

In this case you are asking for how you can dynamically filter by tags
(in an AND search):

qs = TaggedObjects.objects.filter( .. )
for tag in tag:
  qs = qs.filter(tags__tag=tag)

If you wanted to filter on (tag a or tag b) and tag c:
qs = qs.filter(Q(tags__tag=taga) | Q(tags__tag=tagb)).filter(tags__tag=tagc)

I'll leave it up to you to turn that into something dynamic :P

Be aware, each tag you 'AND' filter on adds another join - the joys of RDBMS


Cheers

Tom

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@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