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.