On 30 marras, 15:29, Marek Brzóska <brzoskama...@gmail.com> wrote:
> Has the matter been completely put away?
>
> I would like to bring it up again.
>
> I have Articles and Categories. An Article belongs to Categories:
>
> class Category(model):
>   pass
> class Article(model):
>   category = ManyToManyField(Category)
>   status = CharField(max_length=10)
>
> Now I want all categories with articles that have status different than
> "archived".
>
> I cannot do this with django's ORM!
>
> Category.objects.filter(~Q(article_status="archived"))
>
> will result in a query like this (simplified for readibility):
> SELECT * FROM
> category LEFT OUTER JOIN articlecategory ON category.id =
> articlecategory.category_id
> WHERE NOT
> "category"."id" IN (
>   SELECT U1."category_id"
>   FROM "articlecategory" U1 INNER JOIN "article" U2 ON (U1."article_id" =
> U2."id")
>   WHERE
>   (
>       U2."status" = 'Archived'
>       AND U1."category_id" IS NOT NULL
>    )
> )
>
> The key problem here is that the ~Q() part negates whole big part of SQL
> query, and instead of getting all categories with at least one not archived
> article, I get all categories that have no archived articles! You must
> agree, that it is not very unlikely that someone wants to query for sth
> like this. I cannot use Q(__lt)|Q(__gt) becouse this is not integer. If
> status was enumerated, I could select all values that are different than
> "archived". But in this case I cannot do anything (except custom sql which
> seems like overkill to such simple need).

Hmmh, it would be nice if there was a way to get the wanted query
using the ORM.

Still, if ~Q() is different than __ne that is going to be somewhat
surprising for those users who do not know the ORM well.

For other solutions, one way is custom lookups. They might be reality
for 1.6, see: #16187. Using custom lookups you could have __not_in and
__ne if you so wish.

Another solution might be some sort of aliasing support:
    qs.alias(articles1='article',
subquery=False).exclude(articles1__category='archived')
in general I would really like to have aliasing support, it could
allow for some fancy things, like aliasing raw SQL into the query...

All in all I think it is better to have some way to get the wanted
query out of the ORM than no way at all. Even if that way is a bit non-
obvious.

 - Anssi

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

Reply via email to