On Fri, Nov 30, 2012 at 1:29 PM, 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"))

What precisely is wrong with:

Category.objects.exclude(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).
>
> Adding not equal operator (say __ne) would allow to do this really simply:
> Category.objects.filter(article_status__ne="archived")
>
> potentially resulting with query like this:
> SELECT * FROM
> category LEFT OUTER JOIN articlecategory ON category.id =
> articlecategory.category_id
> WHERE
> "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
>    )
> )
>
> My question is why deny user such obvious usage of ORM?
>
> And btw, "not_in" would be really usefull too, argument the same, but I want
> to exclude three statuses ("archived", "deleted" and "draft").

Category.objects.exclude(article_status__in=[...])


Cheers

Tom

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