W
W
WebDeveloper20162016-11-26 15:19:32
Django
WebDeveloper2016, 2016-11-26 15:19:32

How to get all people starting with a list of letters?

The database contains a list of people. It is necessary if people.name starts with a letter in the list, then take it from the database. How to make such a filter? Those. this is not just filter startswith, but so that the name could begin with any of the letters in the list. For example, pick up all the people whose name starts with V through D. And be sure to do this with a request. It is impossible to take the entire list and filter the necessary ones using python tools.
I found this way (although I haven't tested it yet)

Model.objects.filter(any([Q(name__startswith=letter) for  letter in 'abc']))

but I don't know how to add other conditions to it. Those. I also have other filters for the same request.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
M
Max, 2016-11-27
@zenwalker

On small tables, you can use regular
Model.objects.filter(name__iregex=r'^([в-д])')

R
Roman Kitaev, 2016-11-26
@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))
)

Understand :)

N
neatsoft, 2016-11-26
@neatsoft

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)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question