2012/11/30 Tom Evans <tevans...@googlemail.com>

> 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')
>
It excludes all categories that have at least one archived article.

And I want categories that have at least one NOT archived article.

Example: I have one category: politics. I have two articles in this
category: "Vote Obama!" which archived and "U.S wars" which is not archived.
Category.objects.exclude(article_status='archived')
will show no categories, while I want my only category to show, because
there is one not archived article, "U.S. wars".


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


-- 
pozdrawiam,
Marek Brzóska

brzoskama...@gmail.com

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