【问题标题】:Sort by display name instead of actual value按显示名称而不是实际值排序
【发布时间】:2011-01-02 03:56:21
【问题描述】:

考虑这个示例模型:

MODEL_CHOICES = ( (u"垃圾邮件", u"垃圾邮件"), (u"XOUP", u"蛋汤"), )

(截图)

type = models.CharField(max_length=4, Choices=MODEL_CHOICES)

(实际的实现是特定领域的,并且是非英语的,所以这个示例必须这样做。)

在构建查询时,我想按该类型字段对结果进行排序,并将结果呈现给用户。当然,我想按该字段的显示名称进行排序。

类似的东西:

documents = MyModel.objects.filter(...).order_by("type")

但是,[query-set].order_by([field]) 只允许按字段名称排序,这将导致 SPAM

考虑这组按类型排序的实例:

姓名 |类型

obj1 |垃圾邮件

obj2 |垃圾邮件

obj3 |垃圾邮件

obj4 | XOUP

obj5 | XOUP

但这是用户将看到的顺序,即用户将看到显示名称,而不是类型列的内部字段值:

姓名 |类型

obj1 |垃圾邮件

obj2 |垃圾邮件

obj3 |垃圾邮件

obj4 |鸡蛋汤

obj5 |鸡蛋汤

在人类用户眼中没有正确排序。

Django 中是否有允许按显示名称排序的功能?还是一种“手动”完成此任务的方法? (重命名选项以使显示名称与实际值具有相同的顺序不是一个选项。)

【问题讨论】:

    标签: django sorting django-queryset


    【解决方案1】:

    如果结果集足够小,您可以在代码中对结果进行内存排序。 我想不出任何体面的方法来对数据库级别的结果进行排序。如果您使用知道显示名称的存储过程当然是可能的,但是您必须编写原始 sql。 至于手动排序 - 你可以使用这样的东西:

    obj_list = list(Model.objects.all())
    import operator
    obj_list.sort(key=operator.methodcaller('get_foo_display'))
    

    这里有一些关于如何在 Python 中对列表进行排序的好例子:http://wiki.python.org/moin/HowTo/Sorting

    【讨论】:

    • 谢谢。运算符的用法看起来很漂亮,我不知道。
    【解决方案2】:

    假设显示名称也来自模型,那么您可以按该字段排序以根据需要对选项进行排序。

    MODEL_CHOICES = MyModel.objects.all().values_list('value_field', 'display_field').order_by('display_field')
    ...
    type = models.CharField(max_length=4, choices=MODEL_CHOICES)
    

    如果选项是您问题中的常量,那么您可以简单地更改常量中的顺序。

    MODEL_CHOICES = ((u"XOUP", u"Eggsoup"), (u"SPAM", u"Spam"), )
    

    最后,选择只是一个元组列表,因此您可以使用普通的 Python 排序进行排序。在第二个元素上对元组列表进行排序的Python wiki has a nice example

    【讨论】:

    • 马克,谢谢你的回答。但是,这与选择的排序顺序无关,而与结果的顺序有关。我已经编辑了原始问题以澄清这一点。
    • 我仍然不清楚您从哪里获得显示名称。那是模型的一部分吗?
    • 这是 Django 的一个特性 - 当您将选项定义为双元组时,第一项成为存储在表中的实际值,第二项是显示名称,例如,在管理员中或从模型创建表单时使用。见这里:djangoproject.com/documentation/models/choices
    • 是的,我明白这一点。我的问题是你如何定义选择?您是将它们定义为常量还是从查询集中生成选择?
    • 我将它们定义为常量。尽管如此,在模型中对它们重新排序并不能解决上述问题。
    猜你喜欢
    • 1970-01-01
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    相关资源
    最近更新 更多