简短问题:在Django中,是否有一种方法可以基于字段的字母顺序来查找下一行,并且不区分大小写?Django:额外领域的比较
长问题:我在数据库中有一些单词,以及它们的详细视图。我希望能够按字母顺序浏览单词。所以我需要按字母顺序找出上一个和下一个单词的ID。现在我要做的就是以下(原是存储字的名称的字段):
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
前出现,这是不我想要的是。为了避免这个问题,在另一种观点 - 在这里我列出所有的话,我都利用它增加了一个额外的字段的自定义模型管理器中,这样
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)'})
,并在词的定义我添加
objects = models.Manager()
alpha = CaseInsensitiveManager()
这样,我可以做的查询,如
Word.alpha.all().order_by('lower')
,并得到所有单词按字母顺序不分的情况。但我不能做
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
事实上基于extra fields Django将不会接受field lookups。那么,我应该做什么(缺少编写自定义SQL)呢?
奖金问题:我看到至少在我正在做的更多的问题。首先,我不确定表现。我认为根本没有查询时,我定义previous_words
和next_words
,当我定义previous
和next
在数据库中的唯一查找会发生被执行,产生查询这或多或少
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
。
谢谢!我在原型阶段使用SQLite,但我想我将不得不立即选择MySQL。 – Andrea 2011-04-22 17:04:35
当然(当然,sql lite也有一些整理选项:http://stackoverflow.com/questions/1188749/how-to-change-the-collation-of-sqlite3-database-to-sort-case -insensitively – 2011-04-22 17:09:15