首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django:额外字段的比较

问Django:额外字段的比较
EN

Stack Overflow用户
提问于 2011-04-22 13:56:04
回答 1查看 481关注 0票数 0

简短的问题:中是否有一种方法可以根据某个字段的字母顺序,以不区分大小写的方式找到下一行?

长问题:--我在数据库中有一些单词,以及它们的详细视图。我希望能够按字母顺序浏览这些单词。所以我需要按字母顺序找出前一个和下一个单词的id。现在,我所做的工作如下(原始字段是存储单词名称的字段):

代码语言:javascript
复制
class Word(models.Model):
    original = models.CharField(max_length=50)
    ...

    def neighbours(self):
        """
        Returns the words adjacent to a given word, in alphabetical order
        """
        previous_words = Word.objects.filter(
            original__lt=self.original).order_by('-original')
        next_words = Word.objects.filter(
            original__gt=self.original).order_by('original')
        previous = previous_words[0] if len(previous_words) else None
        next = next_words[0] if len(next_words) else None
        return previous, next

问题是,这做了区分大小写的比较,所以Foo出现在bar之前,这不是我想要的。为了避免这个问题,在另一个视图中,我列出了所有单词,我使用了一个自定义模型管理器,它添加了一个额外的字段,如下所示

代码语言:javascript
复制
class CaseInsensitiveManager(models.Manager):

    def get_query_set(self):
        """
        Also adds an extra 'lower' field which is useful for ordering
        """
        return super(CaseInsensitiveManager, self).get_query_set().extra(
            select={'lower': 'lower(original)'})

在单词的定义中,我添加

代码语言:javascript
复制
objects = models.Manager()
alpha = CaseInsensitiveManager()

通过这种方式,我可以执行如下的查询

代码语言:javascript
复制
Word.alpha.all().order_by('lower')

把所有单词按字母顺序排列,不管情况如何。但我做不到

代码语言:javascript
复制
class Word(models.Model):
    original = models.CharField(max_length=50)
    ...

    objects = models.Manager()
    alpha = CaseInsensitiveManager()

    def neighbours(self):
        previous_words = Word.objects.filter(
            lower__lt=self.lower()).order_by('-lower')
        next_words = Word.objects.filter(
            lower__gt=self.lower()).order_by('lower')
        previous = previous_words[0] if len(previous_words) else None
        next = next_words[0] if len(next_words) else None
        return previous, next

事实上,Django不会接受基于字段查找的额外字段。那么,我应该做什么(除了编写自定义SQL)?

奖金问题:,至少我看到了我正在做的事情中的更多问题。首先,我对表演不太确定。我假设在定义previous_words和next_words时根本不执行查询,而在定义previous和next时,数据库中的唯一查找将发生,从而产生或多或少的查询。

代码语言:javascript
复制
SELECT Word.original, ..., lower(Word.original) AS lower
WHERE lower < `foo`
ORDER BY lower DESC
LIMIT 1

是这样的吗?还是我做了什么会使数据库太慢的事情?关于Django ORM的内部工作,我不知道足够的细节。

第二个问题是,我实际上不得不用不同的语言来处理单词。考虑到我知道每个单词的语言,是否有办法使它们按字母顺序排列,即使它们有非ASCII字符。例如,我希望méchant,moche按这个顺序排列,但是我得到了moche,méchant。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-04-22 16:51:53

数据库应该能够为您进行这种排序,并且它应该能够这样做,而不需要“低级”函数。

实际上,您需要修复的是数据库排序和编码。

例如,如果使用mysql,可以使用字符集utf8和排序规则utf8_general_ci。

如果该排序规则不适用于您,则可以根据您的需要和数据库尝试其他排序规则。但是在查询中使用一个额外的字段和一个函数是一个丑陋的解决方法,它会减缓应用程序的速度。

mysql和postgresql中也有许多排序规则选项可用:

http://dev.mysql.com/doc/refman/5.5/en/charset-mysql.html http://stackoverflow.com/questions/1423378/postgresql-utf8-character-comparison

但这绝对是在db级别进行优化的好机会。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5756158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档