Задать вопрос
@Animkim
Питон вокруг меня

Django qs.extra(select=)?

Не силён в sql, точнее только вчера прочитал основы для самых маленьких.
actions = ('не', ' важно', 'что тут')
select = {'workflow_date': 'SELECT MAX(created_at) FROM workflow_item 
           WHERE workflow_item.info_id = info.id AND workflow_item.kind IN {actions!r}'.format(actions=actions)}

Если условие WHERE не выполняется то workflow_date = None, мне нужно избавиться от этого эффекта. Отличным вариантом было бы заменить None на какую-нибудь дефолтную дату. В общем может кто-нибудь подкинет мысль как это сделать точнее как это сделать в sql.
После этого я просто применяю order_by('-workflow_date') и если в результате есть None то они оказываются первыми.
  • Вопрос задан
  • 864 просмотра
Подписаться 3 Оценить Комментировать
Решения вопроса 1
@Animkim Автор вопроса
Питон вокруг меня
Задача из разряда сортировка авторов по последней фантастической книге
select = {'workflow_date': 'SELECT MAX(CASE WHEN workflow_item.kind IN {actions!r} THEN created_at '
                                       'ELSE DATE(\'2000-01-01 00:00:00.000\') END) '
                                       'FROM workflow_item '
                                       'WHERE workflow_item.info_id = info.id'.format(actions=actions)}


Решение оказалось простым, может кому пригодится, хотя конечно у каждого своя задача со своими условиями.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
sim3x
@sim3x
from django.db import models


class Author(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name


class Book(models.Model):
    BOOK_TYPE_FICTION = 0
    BOOK_TYPE_NONFICTION = 1
    BOOK_TYPE = (
            (BOOK_TYPE_FICTION, 'fiction'),
            (BOOK_TYPE_NONFICTION, 'nonfiction'),
    )

    author = models.ForeignKey(Author, related_name='book_author')
    name = models.CharField(max_length=200)
    book_type = models.IntegerField(default=BOOK_TYPE_FICTION)
    created_at = models.DateField()

    def __str__(self):
        return '"%s", author: %s' % (self.name, self.author.name)


from datetime import date
from books.models import Author, Book


a0 = Author.objects.create(name='Edgar Allan Poe')

Book.objects.bulk_create([
    Book(author=a0, name="The Black Cat", book_type=Book.BOOK_TYPE_FICTION, created_at=date(1843, 8, 19)),
    Book(author=a0, name="The Cask of Amontillado", book_type=Book.BOOK_TYPE_NONFICTION, created_at=date(1853, 8, 19)),
    Book(author=a0, name="A Descent into the Maelström", book_type=Book.BOOK_TYPE_NONFICTION, created_at=date(1863, 8, 19)),
    Book(author=a0, name="The Facts in the Case of M. Valdemar", book_type=Book.BOOK_TYPE_FICTION, created_at=date(1873, 8, 19)),
])

a1 = Author.objects.create(name='Author fiction')

Book.objects.bulk_create([
    Book(author=a1, name="1943", book_type=Book.BOOK_TYPE_FICTION, created_at=date(1943, 8, 19)),
    Book(author=a1, name="1953", book_type=Book.BOOK_TYPE_FICTION, created_at=date(1953, 8, 19)),
    Book(author=a1, name="1963", book_type=Book.BOOK_TYPE_FICTION, created_at=date(1963, 8, 19)),
    Book(author=a1, name="1973", book_type=Book.BOOK_TYPE_FICTION, created_at=date(1973, 8, 19)),
])

a2 = Author.objects.create(name='Author non fiction')

Book.objects.bulk_create([
    Book(author=a2, name="1943", book_type=Book.BOOK_TYPE_NONFICTION, created_at=date(1943, 8, 19)),
    Book(author=a2, name="1953", book_type=Book.BOOK_TYPE_NONFICTION, created_at=date(1953, 8, 19)),
    Book(author=a2, name="1963", book_type=Book.BOOK_TYPE_NONFICTION, created_at=date(1963, 8, 19)),
    Book(author=a2, name="1973", book_type=Book.BOOK_TYPE_NONFICTION, created_at=date(1973, 8, 19)),
])


from django.db.models import Case, When

ids = Book.objects.filter(book_type=Book.BOOK_TYPE_FICTION).order_by('-created_at').values_list('author', flat=True).distinct()

preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(ids)])

Author.objects.filter(pk__in=ids).order_by(preserved)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы