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.