Django按整数值排序,而不是选择字段的字符串值

时间:2016-02-11 16:59:44

标签: python django

我在使用Django选择字段时遇到了一些麻烦。我编写了代码来计算每个StudySpace模型的最后5个结果的平均评分,并将这些评级存储为字符串,即"忙碌","相当繁忙"等等。

我能做到这一点没问题。但是,我希望能够在索引页面中对StudySpaces进行排序,但是要按其平均评级(作为旧的整数值)进行排序。

我已经尝试了

study_space_list = StudySpace.objects.order_by('avg_rating')

但是当我这样做时,这些记录按字母顺序排序shown here,而理想情况下我希望它们使用选择元组中的相应数值进行排序。即忙:1,空:5。

评级模型以及相应的选择如下

class Rating(models.Model):
    studyspace = models.ForeignKey(StudySpace, on_delete=models.CASCADE)
    BUSY = 1
    QUITE_BUSY = 2
    AVERAGE = 3
    QUITE_EMPTY = 4
    EMPTY = 5
    rating_choices = (
        (BUSY, 'Busy'),
        (QUITE_BUSY, 'Quite Busy'),
        (AVERAGE, 'Average'),
        (QUITE_EMPTY, 'Quite Empty'),
        (EMPTY, 'Empty'),
    )
    rating = models.IntegerField(choices=rating_choices, default=AVERAGE)

我希望按平均分数订购StudySpaces的简化视图如下所示

def index(request):
    study_space_list = StudySpace.objects.order_by(<<<NO CLUE WHAT TO DO HERE>>>)
    context = {'study_space_list': study_space_list}
    return render(request, 'spacefinder/index.html', context)

平均评分由StudySpace在每次更新时计算

class StudySpace(models.Model):
    department = models.ForeignKey(Department, on_delete=models.CASCADE)
    space_name = models.CharField(max_length=200, unique=True)
    avg_rating = models.CharField(default='Average', max_length=20)

    def save(self, *args, **kwargs):
        """Recalculates avg_rating on save"""
        query_set = Rating.objects.filter(studyspace=self.id).order_by('-id')[:10]
        if query_set.exists():
            average = query_set.aggregate(Avg('rating')).get('rating__avg')
            self.avg_rating = get_busyness_score(average)
        super(StudySpace, self).save(*args, **kwargs)


def get_busyness_score(value):
    return Rating.rating_choices[round(value)-1][1]

1 个答案:

答案 0 :(得分:1)

您不应该依赖于更改数据库数据以适应您希望在模板中显示的方式。如果您对包含整数字符串的CharField进行排序,则它只会按字典顺序排序,这不是您想要的,因为21小于3,因为3通过比较第一个数字来增大。

解决方案并不难,只需将avg_rating更改为IntegerField或更好,DecimalField,专门处理人类可读数字。如果你想在模板中添加一些花哨的东西,你总是可以编写一个自定义模板标签来显示数字周围的额外内容。

阅读关于what is Decimal的python doc,并阅读有关如何创建custom template tag的django doc。