фильтрация по вычисленным (дополнительным ()) полям - PullRequest
4 голосов
/ 28 августа 2010

Кто-нибудь знает способ фильтрации QuerySet по полю, которое было добавлено с помощью метода extra ()?

Например, это то, что я хотел бы сделать

_list_items = ListItem.objects.filter(list=1).extra(select=
      'SELECT value AS "type" FROM list_item_optional 
       WHERE list_item_optional.list_optional_id=1 
       AND list_item_optional.list_item_id = list_item.id')
_list_items = _list_items.filter(type='A')

Я знаю, что вышеописанная ситуация недопустима, но каков обходной путь в Джанго?

Точно так же недопустимый способ выполнения SQL-кода также недопустим, например: SELECT fieldA, fieldB, (SELECT blahblah from tableY WHERE id=1) AS "bla" FROM tableX WHERE "bla" = 'x'

Фильтрация по вычисляемому полю просто не разрешена в Postgres ... Обойти кого-нибудь? Проблема становится больше, потому что оператор SQL (получение QuerySet) является динамическим и определяется только во время выполнения.

Приветствия

Прикрепление моделей:

class List(models.Model):
    account = models.ForeignKey(Account)
    created_date = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(AccountUser, related_name='x10')
    updated_date = models.DateTimeField(null=True, blank=True)
    updated_by = models.ForeignKey(AccountUser, null=True, blank=True, related_name='x11')
    is_deleted = models.BooleanField(default=False)
    name = models.CharField(max_length=50)

    objects_active = DeletedManager()

    class Meta:
        db_table = u'list'

class ListItem(models.Model):
    list = models.ForeignKey(List, db_index=True)
    key = models.CharField(max_length=50)
    name = models.CharField(max_length=100)

    class Meta:
        db_table = u'list_item'
        unique_together = ("list", "key")


class ListOptional(models.Model):
    list = models.ForeignKey(List, db_index=True)
    name = models.CharField(max_length=50)
    is_searchable = models.BooleanField()

    class Meta:
        db_table = u'list_optional'


class ListItemOptional(models.Model):
    list_item = models.ForeignKey(ListItem, null=True, db_index=True)
    list_optional = models.ForeignKey(ListOptional, null=True)
    value = models.CharField(max_length=100)

    class Meta:
        db_table = u'list_item_optional'

Ответы [ 2 ]

0 голосов
/ 04 ноября 2010

Попробуйте это:

_list_items = ListItem.objects.filter(list=1).extra(select={'type':
    'SELECT value AS "type" FROM list_item_optional '
    'WHERE list_item_optional.list_optional_id=1 '
    'AND list_item_optional.list_item_id = list_item.id')
_list_items = _list_items.extra(where="`type` = 'A'")

Хитрость заключается в использовании аргумента extra() where, но в последующем применении extra(), так что построенный запрос уже имеет новое поле.

0 голосов
/ 28 августа 2010
SELECT value AS "type" FROM list_item_optional WHERE list_item_optional.list_optional_id=1 AND list_item_optional.list_item_id = list_item.id

Предложение WHERE представляет собой комбинацию двух условий: list_item_optional.list_optional_id=1 и list_item_optional.list_item_id = list_item.id. Разве вы не можете применять условия фильтра напрямую, а не выбирать их как дополнительные, а затем фильтровать? Я пишу этот ответ, не видя рассматриваемых моделей. Предоставление исходного кода для моделей поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...