我可以在django中使用方法进行订购吗?

时间:2014-05-12 15:10:14

标签: python django

我可以在django中使用方法进行排序吗?

class Question(models.Model):
    writer = models.ForeignKey(settings.AUTH_USER_MODEL, null=True,
                               related_name='questions',
                               on_delete=models.SET_NULL)
    contents = models.TextField()

    def date_of_receive(self):
        try:
            return self.answers.first().creation.date()
        except AttributeError:
            return None
        except:
            assert False, 'error'

class Answer(models.Model):
    writer = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='answers')
    contents = models.TextField()
    question = models.ForeignKey(Question, related_name='answers', null=True,
                                 on_delete=models.SET_NULL)

我希望问题按'date_of_receive'排序......

我该怎么办?

3 个答案:

答案 0 :(得分:4)

您可以通过两种方式订购:通过使用依赖于数据库为您排序的order_by,或者将所有结果提取到您的申请流程中。记忆并在那里排序。数据库对Python或您的方法一无所知,因此如果您在内存中排序,则只能通过方法的结果进行排序。

但是,在这种情况下,您的方法无论如何都可以简化为数据库调用。 .order_by('answers__creation')可能会提供您想要的内容,但您可以使用聚合和注释来仅获取FIRST创建日期时间。我觉得它看起来像这样:

from django.db.models import Min

Question.objects.annotate(date_of_receive=Min('answers__creation')).order_by('date_of_receive')

请注意,在非常大的数据集上无法有效地执行此操作。如果你有数十万行,那么你根本不应该在应用程序内存中排序,而在数据库内存中排序需要很长时间。此时,您需要对数据进行非规范化。但是,只有当你真的认为你的数据集会变得那么大时才这样做,因为非规范化数据是引入细微错误的好方法。

答案 1 :(得分:1)

你不能。 Django的order_by()在数据库级别上工作。

虽然您可以通过执行类似

的操作来实现排序
sorted(Question.objects.all(), key=lambda k: k.date_of_receive())

答案 2 :(得分:0)

你应该在python本身对结果进行排序。由于 date_of_receive 是一种方法,因此无法在数据库级别对其进行排序。