前提:这里根据下面的两个基础model来讲解一下model field的排序问题
class Business(models.Model):
name = models.CharField(_("名称"), max_length=LEN_NORMAL, null=True)
type = models.CharField(_("类别"), max_length=LEN_SHORT, choices=TYPE)
is_access_cleanup = models.BooleanField(_("是否接入清理"), default=False)
class Meta:
db_table = 'business'
verbose_name = verbose_name_plural = "业务系统"
class Database(models.Model):
business = models.ForeignKey(Business, related_name="databases", on_delete=models.CASCADE)
alias_name = models.CharField(_("服务名"), max_length=LEN_LONG, null=True)
ip = models.GenericIPAddressField(_("数据库IP"))
port = models.SmallIntegerField(_("端口"), default=1521)
class Meta:
db_table = 'database'
verbose_name = verbose_name_plural = "数据库"
基础排序
在日常开发中,我没经常遇到需要根据model字段排序的功能。常用的model排序方法有两种
方法一:order_by函数
例如:我们需要根据字段ip
对Database
进行排序。我们可以这样
Database.objects.all().order_by('-ip')
其中,'ip'表示升序; '-ip'表示降序。升序时可以不写,是默认。
也可以这样使用
Database.objects.order_by('-ip')
.all()可以省略。 默认查询所有。 也可以结合filter等函数一起使用 。
也可以多个字段一起查询
Database.objects.order_by('-ip', 'port')
含义:先根据ip进行倒序排列,再根据port进行正序排列
方法二:model中的Meta选项ordering
class Database(models.Model):
business = models.ForeignKey(Business, related_name="databases", on_delete=models.CASCADE)
alias_name = models.CharField(_("服务名"), max_length=LEN_LONG, null=True)
ip = models.GenericIPAddressField(_("数据库IP"))
port = models.SmallIntegerField(_("端口"), default=1521)
class Meta:
db_table = 'database'
verbose_name = verbose_name_plural = "数据库"
ordering = ('-ip',)
ordering它是一个字符串的列表或元组。每个字符串是一个字段名,前面带有可选的“-”前缀表示倒序。前面没有“-”的字段表示正序。使用"?"来表示随机排序。
也可以多字段查询
ordering = ('-ip', 'port')
功能跟order_by
一样
根据外键字段排序
例如,我想实现根据Business
中的type
字段对Database
进行排序
我们可以这样实现,使用双下划线__
在排序子句中遵循关系来实现
Database.objects.order_by('business__type')
写在最后
排序并不是没有任何代价的操作。你向ordering属性添加的每个字段都会产生你数据库的开销。