在 Django 中设置排序以使用特定于语言的顺序
Set ordering in django to use language specific order
编辑: 我刚刚注意到下面描述的行为只出现在我的开发机器上,而不出现在生产服务器上。在生产服务器上,它是按需要排序的。它必须在我的 PostgreSQL 服务器的设置中。
我有一个 Django 应用程序,其中包含以下模型,这些模型的顺序设置为 class Meta
:
class Akutsomatik(models.Model):
bereichname = models.CharField(max_length=200)
class Meta:
ordering = ['bereichname']
def __str__(self):
return self.name
# This model is only included in the example for better understanding
class Klinik(models.Model):
name = models.CharField(max_length=200)
akutsomatik = models.ManyToManyField(Akutsomatik, blank=True)
def __str__(self):
return self.name
还有我的模板:
{% if klinik.akutsomatik.all %}
<ul>
{% for akutsomatik in klinik.akutsomatik.all %}
<li>{{ akutsomatik }}</li>
{% endfor %}
</ul>
{% endif %}
问题是我的应用程序的数据是德语的,并且排序设置为 UTF-8。输出看起来像这样:
Augenchirurgie / Ophtalmologie
Brustchirurgie
Viszeralchirurgie
Wiederherstellende Chirurgie
Ästhetische Chirurgie
但在德语中应该是这样的:
Ästhetische Chirurgie
Augenchirurgie / Ophtalmologie
Brustchirurgie
Viszeralchirurgie
Wiederherstellende Chirurgie
注意 Ästhetische Chirurgie
应该在 Augenchirurgie / Ophtalmologie
之前。
有谁知道是否有办法在 class Meta
中设置排序规则?我尝试了以下描述 here:
from django.db.models import Func
class Meta:
ordering = [Func('bereichname',
function='utf8_general_ci',
template='(%(expressions)s) COLLATE "%(function)s"')
]
但是我收到以下模板错误:
collation "utf8_general_ci" for encoding "UTF8" does not exist
LINE 1: ...ER BY ("klinik_finder_akutsomatik"."bereichname") COLLATE "u...
我也尝试将 function
设置为 function='de_DE'
。它没有给我任何错误,但顺序也没有改变(在 makemigrations
和 migrate
之后)。
也许有人可以指导我正确的方向。谢谢。
从 Django 版本 3.2 开始,您可以使用 kwarg db_collation
[Django docs]:
直接在字段本身中指定 CharField
或 TextField
的排序规则
class Akutsomatik(models.Model):
bereichname = models.CharField(max_length=200, db_collation='utf8_general_ci')
...
继续看,您的错误似乎是因为您使用的排序规则在 PostgreSQL 中不存在,您可以使用的等效排序规则是 und-x-icu
,如该问题中所述:Install utf8 collation in PostgreSQL。因此,如果您将 utf8_general_ci
替换为 und-x-icu
,您的解决方案应该有效。
编辑: 我刚刚注意到下面描述的行为只出现在我的开发机器上,而不出现在生产服务器上。在生产服务器上,它是按需要排序的。它必须在我的 PostgreSQL 服务器的设置中。
我有一个 Django 应用程序,其中包含以下模型,这些模型的顺序设置为 class Meta
:
class Akutsomatik(models.Model):
bereichname = models.CharField(max_length=200)
class Meta:
ordering = ['bereichname']
def __str__(self):
return self.name
# This model is only included in the example for better understanding
class Klinik(models.Model):
name = models.CharField(max_length=200)
akutsomatik = models.ManyToManyField(Akutsomatik, blank=True)
def __str__(self):
return self.name
还有我的模板:
{% if klinik.akutsomatik.all %}
<ul>
{% for akutsomatik in klinik.akutsomatik.all %}
<li>{{ akutsomatik }}</li>
{% endfor %}
</ul>
{% endif %}
问题是我的应用程序的数据是德语的,并且排序设置为 UTF-8。输出看起来像这样:
Augenchirurgie / Ophtalmologie
Brustchirurgie
Viszeralchirurgie
Wiederherstellende Chirurgie
Ästhetische Chirurgie
但在德语中应该是这样的:
Ästhetische Chirurgie
Augenchirurgie / Ophtalmologie
Brustchirurgie
Viszeralchirurgie
Wiederherstellende Chirurgie
注意 Ästhetische Chirurgie
应该在 Augenchirurgie / Ophtalmologie
之前。
有谁知道是否有办法在 class Meta
中设置排序规则?我尝试了以下描述 here:
from django.db.models import Func
class Meta:
ordering = [Func('bereichname',
function='utf8_general_ci',
template='(%(expressions)s) COLLATE "%(function)s"')
]
但是我收到以下模板错误:
collation "utf8_general_ci" for encoding "UTF8" does not exist
LINE 1: ...ER BY ("klinik_finder_akutsomatik"."bereichname") COLLATE "u...
我也尝试将 function
设置为 function='de_DE'
。它没有给我任何错误,但顺序也没有改变(在 makemigrations
和 migrate
之后)。
也许有人可以指导我正确的方向。谢谢。
从 Django 版本 3.2 开始,您可以使用 kwarg db_collation
[Django docs]:
CharField
或 TextField
的排序规则
class Akutsomatik(models.Model):
bereichname = models.CharField(max_length=200, db_collation='utf8_general_ci')
...
继续看,您的错误似乎是因为您使用的排序规则在 PostgreSQL 中不存在,您可以使用的等效排序规则是 und-x-icu
,如该问题中所述:Install utf8 collation in PostgreSQL。因此,如果您将 utf8_general_ci
替换为 und-x-icu
,您的解决方案应该有效。