Python 如何以Django中QuerySet的排序方式对列表进行排序?
我有一个模型,它的元类下有一个排序字段。当我执行查询并返回模型的QuerySet时,它是按照指定的顺序进行的。但是,如果此模型的实例位于列表中,并且在列表上执行sort方法,则顺序与我想要的顺序不同。是否有方法对模型实例列表进行排序,使其顺序与模型定义中指定的顺序相同?您的问题的答案是不同程度的“是”,并有一些手动要求。如果您所说的Python 如何以Django中QuerySet的排序方式对列表进行排序?,python,django,django-models,Python,Django,Django Models,我有一个模型,它的元类下有一个排序字段。当我执行查询并返回模型的QuerySet时,它是按照指定的顺序进行的。但是,如果此模型的实例位于列表中,并且在列表上执行sort方法,则顺序与我想要的顺序不同。是否有方法对模型实例列表进行排序,使其顺序与模型定义中指定的顺序相同?您的问题的答案是不同程度的“是”,并有一些手动要求。如果您所说的list是指通过复杂查询形成的queryset,那么,请确保: queryset.order_by(ClassName.Meta.ordering) 或 或 如果您
list
是指通过复杂查询形成的queryset
,那么,请确保:
queryset.order_by(ClassName.Meta.ordering)
或
或
如果您没有使用queryset,那么当然您仍然可以进行排序,就像python中任何人对复杂对象进行排序一样:
- 比较器
- 指定键
- 装饰/分类/取消装饰
您的问题的答案是不同程度的“是”,并有一些手动要求。如果您所说的
list
是指通过复杂查询形成的queryset
,那么,请确保:
queryset.order_by(ClassName.Meta.ordering)
或
或
如果您没有使用queryset,那么当然您仍然可以进行排序,就像python中任何人对复杂对象进行排序一样:
- 比较器
- 指定键
- 装饰/分类/取消装饰
不是自动的,但需要一些工作,是的。您需要定义一个comparator函数(或model类上的cmp方法),该函数可以根据相关属性比较两个模型实例。例如:
class Dated(models.Model):
...
created = models.DateTimeField(default=datetime.now)
class Meta:
ordering = ('created',)
def __cmp__(self, other):
try:
return cmp(self.created, other.created)
except AttributeError:
return cmp(self.created, other)
不是自动的,但是需要一些工作,是的。您需要定义一个comparator函数(或model类上的cmp方法),该函数可以根据相关属性比较两个模型实例。例如:
class Dated(models.Model):
...
created = models.DateTimeField(default=datetime.now)
class Meta:
ordering = ('created',)
def __cmp__(self, other):
try:
return cmp(self.created, other.created)
except AttributeError:
return cmp(self.created, other)
基于Carl的答案,您可以轻松添加使用所有排序字段的功能,甚至可以检测反向排序的字段
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birthday = date = models.DateField()
class Meta:
ordering = ['last_name', 'first_name']
def __cmp__(self, other):
for order in self._meta.ordering:
if order.startswith('-'):
order = order[1:]
mode = -1
else:
mode = 1
if hasattr(self, order) and hasattr(other, order):
result = mode * cmp(getattr(self, order), getattr(other, order))
if result: return result
return 0
基于Carl的答案,您可以轻松添加使用所有排序字段的功能,甚至可以检测反向排序的字段
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birthday = date = models.DateField()
class Meta:
ordering = ['last_name', 'first_name']
def __cmp__(self, other):
for order in self._meta.ordering:
if order.startswith('-'):
order = order[1:]
mode = -1
else:
mode = 1
if hasattr(self, order) and hasattr(other, order):
result = mode * cmp(getattr(self, order), getattr(other, order))
if result: return result
return 0
+1个不错的解决方案,将排序保持在模型级别,因此无论在何处进行列表排序,都可以透明地执行。+1个不错的解决方案,将排序保持在模型级别,因此无论在何处进行列表排序,都可以透明地执行。非常不错。最好把它放到
模型的子类中。模型也可以这样你就可以在你的模型中使用它了。非常好。最好将其放入models.Model的子类中,这样您就可以在整个模型中使用它。