使用F()表达式查找列表中的位置以更新对象

时间:2015-10-25 23:25:35

标签: python django django-queryset django-database

我有4个BaseReward对象,在Meta类中有(rank,id)的默认顺序。我的目标是更新对象,以便保留它们的相对排名,但从1开始给它们唯一的排名,

最初:

| id | rank |
|----|------|
| 1  | 3    |
| 2  | 2    |
| 3  | 2    |
| 4  | 1    |
调用rerank_rewards_to_have_unique_ranks()之后

应该成为

| id | rank |
|----|------|
| 1  | 4    |
| 2  | 2    |
| 3  | 3    |
| 4  | 1    |

我试图在列表中使用带有查找.index()的F()表达式,但是Django不接受它,因为F()表达式只有一组固定的运算符https://docs.djangoproject.com/en/1.8/topics/db/queries/#filters-can-reference-fields-on-the-model

是否有另一种以优化的方式实现相同的方法,而不将对象带到数据库?

models.py

class BaseReward(models.Model):
    class Meta:
        ordering = ('rank', 'id')    
        # BaseReward.objects.all() gets the objects ordered by 'rank' as in the Meta class, and then by id if two objects have same rank

helper.py

def rerank_rewards_to_have_unique_ranks():

    qs = BaseReward.objects.all() # this would give the rewards of that category ordered by [rank, id]

    id_list_in_order_of_rank = list(qs.values_list('id', flat=True))        # get the ordered list of ids sequenced in order of ranks

    # now I want to update the ranks of the objects, such that rank = the desired rank

    BaseReward.objects.all().update(rank=id_list_in_order_of_rank.index(F('id'))+1)

0 个答案:

没有答案