Django(PostgreSQL)查询过滤器以排除给定字母

时间:2019-05-29 21:43:26

标签: django postgresql

用户发送了以下字母中的一个字母,我想发送适当的回复。

enter image description here

您会注意到西里尔字母和拉丁字母有些混合。我有以下get_queryset方法:

def get_queryset(self):
        SPECIAL_CHARACTERS = [
            'Аь', 'Гl', 'Кх', 'Къ', 'Кl', 'Оь', 'Хь', 'Хl', 'Цl', 'Чl', 'Юь', 'Яь'
        ]
        queryset = WordChechenModel.objects.all().order_by('word_chechen')
        first_letter = self.request.query_params.get('letter', None)
        if first_letter is not None:
            if len(first_letter) == 2:
                queryset = queryset.filter(
                    word_chechen__iregex=r"^w+%s" % first_letter)
            else:
                queryset = queryset.filter(Q(word_chechen__startswith=first_letter) | Q(
                    word_chechen__startswith=first_letter.upper())).exclude(
                    word_chechen__startswith__in=SPECIAL_CHARACTERS)
        return queryset

如果用户发送双(混合)字母的请求,我可以使用正则表达式对其进行过滤,但是如果用户发送请求,可以使用Аь或比我多的SPECIAL_CHARACTERS个字符有问题。

当前,我尝试使用以下查询排除以SPECIAL_CHARACTERS中定义的字母之一开头的所有单词:

queryset = queryset.filter(Q(word_chechen__startswith=first_letter) | Q(
                        word_chechen__startswith=first_letter.upper())).exclude(
                        word_chechen__startswith__in=SPECIAL_CHARACTERS)
            return queryset

但这给了我以下错误:

django.core.exceptions.FieldError: Unsupported lookup 'startswith' for CharField or join on the field not permitted, perhaps you meant s
tartswith or istartswith?

我非常感谢这些想法。处理请求的速度很重要。因此,最好同时查看我的代码。

1 个答案:

答案 0 :(得分:0)

我已经使用正则表达式解决了这个问题,thx nigel222指出了这一点。我在此帖子https://stackoverflow.com/a/2667582/7986808中找到了解决方法
我的工作代码:

def get_queryset(self):
        SPECIAL_CHARACTERS = [
            'Аь', 'Гl', 'Кх', 'Къ', 'Кl', 'Оь', 'Хь', 'Хl', 'Цl', 'Чl', 'Юь', 'Яь'
        ]
        queryset = WordChechenModel.objects.all().order_by('word_chechen')
        first_letter = self.request.query_params.get('letter', None)
        if first_letter is not None:
            if len(first_letter) == 2:
                queryset = queryset.filter(
                    word_chechen__regex=r"^%s" % first_letter)
            else:
                queryset = queryset.filter(
                    word_chechen__regex=r"^%s" % first_letter).exclude(
                        word_chechen__regex=r'(^' + '|^'.join(SPECIAL_CHARACTERS) + ')')
        return queryset