django - QuerySet 递归排序方法
我可能遇到了一个经典的问题,但我找不到任何代码片段能帮我解决。
我想按照全名对这个模型进行排序。
class ProductType(models.Model):
parent = models.ForeignKey('self', related_name='child_set')
name = models.CharField(max_length=128)
def get_fullname(self):
if self.parent is None:
return self.name
return u'%s - %s' % (unicode(self.parent), self.name)
fullname = property(get_fullname)
我尝试按“parent”排序,但出现了无限循环错误。使用“parent__id”排序也不太好。
我不太明白如何使用annotate()来连接字符串字段。
我添加了一个自定义管理器,使用了sorted(),但是它返回的是一个列表对象,这样就导致我的forms.ModelChoiceField无法正常工作。
这是排序的代码
def all(self):
return sorted(super(ProductTypeManager, self), key=lambda o: o.fullname)
在这个Django的丛林里还有什么其他的呢?感谢你的帮助。
5 个回答
0
这可能有效:
ProductType.objects.alL().order_by('parent__name', 'name')
1
或者,如果你想做的是生成一个树形结构,可以看看 django-mptt。这个工具还可以让你手动设置顺序。
2
我可能会创建一个去规范化的字段,然后根据这个字段进行排序。根据你的喜好,你可能想要重写一下 .save() 方法,或者使用信号来填充这个去规范化的字段。
class ProductType(models.Model):
parent = models.ForeignKey('self', related_name='child_set')
name = models.CharField(max_length=128)
full_name = models.CharField(max_length=128*4)
def save(self, *args, **kwargs):
if not full_name:
self.full_name = self.get_fullname()
super(ProductType, self).save(*args, **kwargs)
def get_fullname(self):
if self.parent is None:
return self.name
return u'%s - %s' % (unicode(self.parent), self.name)
然后就可以正常地根据 full_name
进行排序了。