@WebDeveloper2016

Как получить всех людей начинающихся с перечня букв?

В БД лежит список людей. Надо если people.name начинается с буквы находящейся в перечне то забрать его из БД. Как такой фильтр сделать? Т.е. это не просто filter startswith, а чтобы именно с любой из букв в перечне могло имя начинаться. Например забрать всех людей, имя которых начинается с В по Д. Причем обязательно это запросом сделать надо. Нельзя забрать весь список и средствами питона отфильтровать нужных.

Нашел вот такой способ (правда пока не проверял)
Model.objects.filter(any([Q(name__startswith=letter) for  letter in 'abc']))

но не знаю как добавлять к нему другие условия. Т.е. у меня есть помимо этого и другие фильтры к тому же запросу.
  • Вопрос задан
  • 427 просмотров
Пригласить эксперта
Ответы на вопрос 3
zenwalker
@zenwalker
0xABADBABE
На небольших таблицах можно регулярочкой
Model.objects.filter(name__iregex=r'^([в-д])')
Ответ написан
@deliro
letters = 'абвгд'
Model.objects.filter(reduce(
    lambda x,y: (isinstance(x, Q) and x or Q(name__istartswith=x)) | Q(name__istartswith=y), 
    letters
))

# Или

from operator import or_
Model.objects.filter(
    reduce(or_, (Q(name__istartswith=l) for l in letters))
)

Разбирайся :)
Ответ написан
neatsoft
@neatsoft
Life is too short for bad software
import operator
import functools

from django.db.models import Q

from .models import Item


def get_items(letters=''):
    items = Item.objects.filter(active=True)
    items = items.exclude(id__lt=100).exclude(id__gt=200)
    if letters:
        q = functools.reduce(operator.or_, (Q(name__istartswith=l) for l in letters))
        items = items.filter(q)
    return items

get_items('abc')


from django.db.models import Q

from .models import Item


def get_items(letters='', active=None):
    q = Q()
    if len(letters) == 3 and letters[1] == '-':
        letters = (unichr(c) for c in range(ord(letters[0]), ord(letters[2]) + 1))
    for letter in letters:
        q |= Q(name__istartswith=letter)
    if active is not None:
        q &= Q(active=active)
    return Item.objects.filter(q)

get_items(u'абвгд')
get_items(u'в-д')
get_items(u'а-я', True)
Ответ написан
Ваш ответ на вопрос

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

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