2012-08-02 48 views
2

我要订购我的升序QuerySet为了使这种情况:Django的订购查询集升序排列

PRIORITY_CHOICES = (
(1, "P1"), 
(2, "P2"), 
(3, "P3"), 
(4, "P4"), 
(5, "P5"), 
) 

class Task(models.Model): 
    name = models.CharField(max_length=255) 
    priority = models.PositiveIntegerField(choices=PRIORITY_CHOICES) 

现在,因为,优先级可以接受无值。问题是与订购我这样做,我认为代码时查询设置:

task_list = Task.objects.all().order_by("priority") 

这将返回我的查询与设置在优先级的升序对象设定,与无值第一。我想要升序列表,但我想在最后包含None值。我有一个庞大的数据库,所以我有兴趣在数据库级别完成此操作。

+0

查看http://stackoverflow.com/questions/5235209/django-order-by-position-ignoring-null为您的答案。 – astevanovic 2012-08-02 02:33:59

回答

3

这可能是您最好的选择。

import itertools 
q = itertools.chain(
     Task.objects.filter(priority__isnull=False).order_by("priority"), 
     Task.objects.filter(priority__isnull=True)) 
# Then you can iterate over your custom order 
result = [(x.name, x.priority) for x in q] 
+0

谢谢,这看起来不错。我猜测链式函数是C级操作,所以我认为它不应该占用太多内存。 – 2012-08-02 17:48:39

+2

这是一些解决方案,但我更愿意实际返回一个查询集,您可以在其中链接其他调用(过滤器等),以便它可以由管理器的“get_query_set”返回。任何提示? – 2012-09-27 15:40:48

1

您可以使用queryset.order_by('-field')(前缀“ - ”符号)更改顺序以降序排列,但是Django没有办法告诉如何排序空值 - 这是数据库特定的行为。如果使用降序排序仍然会在数据库中首先给出空值 - 请使用queryset.extra(select={'order': 'custom_sql_function(priority)'}).order_by('order'),其中custom_sql_function将字段转换为整数(如果它为空)并且特定于您的数据库引擎。 为了获得更快的性能,您可以在function(field)上创建数据库索引。

+0

谢谢,我会仔细研究一下。 – 2012-08-02 17:48:57