Django自定义order_by
我有一个模型,比如说“汽车”,它有一个外键,比如说“车主”,这个外键可能是空的,也可能有值。
汽车还有一个创建日期。
我想按照日期来排序这些汽车,但如果汽车有车主的话,就要用车主的出生日期来代替汽车的创建日期进行排序。
这样做可以吗?
3 个回答
1
你可以写一个方法,这个方法会根据情况返回合适的日期。如果车子有主人,就返回主人的生日;如果没有主人,就返回创建日期。然后你可以根据这个方法来对你的模型进行排序。
6
这可以通过使用SQL来实现:
Car.objects.filter(...).extra(select={'odate': '''
if(owner_id,
(select date_of_birth from owner_table where id=owner_id),
creation_date
)
'''}).order_by('odate')
if
这个函数是MySQL特有的。如果你使用的是SQLite或Postgres数据库,就应该用case
语句。
6
看看这个类似的问题:在Django中排序查询集的好方法?
你不能使用模型的Meta中的ordering
,因为它只接受一个字段。
https://docs.djangoproject.com/en/dev/ref/models/options/#ordering
你也不能使用查询中的order_by('creation_date', 'birthdate')
,因为如果它们的creation_date
相同,它只会按出生日期排序。
所以,你可以写一个自定义管理器来为你实现自定义排序。
import operator
class CarManager(models.Manager):
def get_query_set(self):
auths = super(CarManager, self).get_query_set().all().order_by('-creation')
ordered = sorted(auths, key=operator.attrgetter('birthday'))
return ordered
class Car(models.Model):
sorted = CarManager()
这样你就可以查询:
Car.sorted.all()
来获取所有排序后的汽车查询集。