Django QuerySet order_by字符串求值



我正试图根据QuerySet中对象作为字符串的求值方式对QuerySet进行排序。

所以我的模型看起来像这样:

class System(models.Model):
  operating_system = models.CharField(...)
  language = models.CharField(...)
  locale = models.CharField(...)
  def __unicode__(self):
    def __clean(orig, new):
      if orig is None or orig == "":
        if new is None or new == "":
          return ""
        else:
          return str(new)
      else:
        if new is None or new == "":
          return str(orig)
        else:
          return str(orig) + " " + str(new)
    name = None
    for attr in System._meta.fields:
      if attr.name != "id":
        name = __clean(name, getattr(self, attr.name))
    for m2mfield in System._meta.many_to_many:
      for object in getattr(self, m2mfield.name).all():
        name = __clean(name, object)  
    if name == "":
      return "Undefined"
    return name

而且,我希望能够进行类似以下的查询:

System.objects.filter(...).order_by('__unicode__')

我想知道是否有一种方法可以在没有定制经理的情况下做到这一点。

谢谢!

__unicode__中,您最终会得到一个表示System对象的字符串。与其每次需要都计算,不如计算一次并保存到模型中。

class System(models.Model):
    operating_system = models.CharField(...)
    language = models.CharField(...)
    locale= models.CharField(...)
    name = models.CharField(editable=False, ...)
    def save(self, *args, **kwargs):
        self.name = self._calculate_name()
        super(System, self).save(*args, **kwargs)
    def __unicode__(self):
        return self.name
    def _calculate_name(self):
        # all that string manipulation and relationship stuff

现在你可以用这个名字很容易地订购

System.objects.filter(...).order_by('name')

这种方法有一些注意事项,它实际上取决于系统的使用。另外,不要担心空间,这是我的观点!


扩展注意事项

由于该字段是"非规范化的",因此它会遇到与其他未规范化的关系数据相同的问题。去规范化可能会引入更新异常(如果通过System模型的save()方法之外的其他途径发生变化,name所依赖的字段或关系可能会在不改变name的情况下发生变化。它还可以减慢写入速度(在这种情况下可能会非常小(,增加空间需求(在我看来,这也不是问题(,还有一大堆谷歌很乐意告诉你的事情。

我认为您需要小心的是随时更新.name,所以请仔细考虑在什么条件下您的"清理"代码会产生不同的结果。例如,如果您有一个操作系统表,您可以在不接触系统表的情况下更改操作系统的描述,那么您必须意识到您的.name不会通过保存到操作系统来更新,它将需要重新计算。有一些机制可以帮助处理类似的信号并覆盖更多的save()方法。您也可以根据需要批量更新它们。

这在很大程度上取决于您的用例,这里没有完全说明。如果你更完整地展示你的用例,那么SO有很多人可以帮助你缩小最佳解决方案的范围。

相关内容

  • 没有找到相关文章

最新更新