간단한 질문 : 대소 문자를 구분하지 않고 Django에서 일부 필드의 사전 순 정렬을 기반으로 다음 행을 찾는 방법이 있습니까?Django : 여분의 필드에 대한 비교
긴 질문 : 나는 데이터베이스에 몇 가지 단어와 상세한 설명을 가지고 있습니다. 알파벳순으로 단어를 탐색 할 수 있기를 바랍니다. 그래서 알파벳순으로 이전 단어와 다음 단어의 이드를 찾아야합니다. 지금 내가 뭘 다음 (원래 단어의 이름을 저장하는 필드입니다)입니다 :
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)'})
같은 및 Word의 정의에 추가 필드를 추가하는 사용자 정의 모델 관리자의 사용을 만들었습니다 - 또 다른 관점에서이 문제를 방지하려면 내가
Word.alpha.all().order_by('lower')
같은 쿼리를 수행하고 관계없이 사건의 알파벳 순서에있는 모든 단어를 얻을 수있는이 방법으로
objects = models.Manager()
alpha = CaseInsensitiveManager()
. 하지만 하지
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에 따라 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
물론 (물론 : sql lite에는 몇 가지 조합 옵션도 있습니다 : http://stackoverflow.com/questions/1188749/how-to-change-the-collation-of-sqlite3-database-to-sort-case - 무감각하게 –