Question

Suppose I have a model "Book" with three fields: name, author_name (as a string), publish_state. Now I want to find out which authors have exactly one published book. This sql query does exactly what I want:

SELECT author_name from books GROUP BY author_name HAVING count(name) = 1 and every(publish_state = 'published');

I'm using Postgres as you can say by the 'every' clause.

Is there a way to do this in django ORM? or do I need to use a raw query for that?

Était-ce utile?

La solution 3

Unfortunately this feature is not implemented in django's ORM, and I don't think it would be any time soon, as it is not a very common query.

I had to use raw SQL. You can find about it here: https://docs.djangoproject.com/en/1.7/topics/db/sql/

Autres conseils

There is probably a better way, but at least you can do the following ...

books = Book.objects.filter(publish_state='published')
authors = {}

for book in books:
    authors.setdefault(book.author, 0)
    authors[book.author] += 1

rookies = [x for x, y in authors.iteritems() if y == 1]

Django uses the having clause when you use filter() after an annotate like annotate(foo=Count('bar')).filter(foo__gt=3). Add in values_list and distinct like so and you should be good:

Book.objects.filter(publish_state='published').values_list('author_name',  flat=True).order_by('author_name').annotate(count_books=Count('name')).filter(count_books=1).distinct()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top