Login
芋圆社区 > 编程 > Django > order_by多条件和随机排序

order_by多条件和随机排序

424
0
2022-01-24
2022-10-13
Hey、小怪兽


多条件排序


  • • 排序在很多地方都会用到,如下图,我想排序根据等级排序
  • userRank = User.objects.all().order_by('-rank')[:50]
  • • 一行很简单的代码,用order_by进行降序,但是这个时候万一同等级的成员咋办,比方说A和B都是Lv3的,但是B的经验值比A多50,这个时候理应说B需要排在前面,但是django会将A排在前面(因为按id的升序来排),这个时候多条件排序就很重要了
  • • 一开始我认为是这样的(错误的写法):
  • userRank = User.objects.all().order_by('-rank').order_by('-Taco').order_by('-nowexp')[:50]
  • • 看起来是很合理,先按等级降序,如果同等级的按Taco降序来排,如果同Taco的按当前经验降序来排,但是这样就错误了,这样写只会按最后一个排序,也就是当前经验降序来排,前面的两个都会无效
  • • 然后我就去看了看这个order_by的方法
  • def order_by(self, *field_names):
        """Return a new QuerySet instance with the ordering changed."""
        assert not self.query.is_sliced, \
            "Cannot reorder a query once a slice has been taken."
        obj = self._chain()
        obj.query.clear_ordering(force_empty=False)
        obj.query.add_ordering(*field_names)
        return obj
    def _chain(self, **kwargs):
        """
        Return a copy of the current QuerySet that's ready for another
        operation.
        """
        obj = self._clone()
        if obj._sticky_filter:
            obj.query.filter_is_sticky = True
            obj._sticky_filter = False
        obj.__dict__.update(kwargs)
        return obj
    def clear_ordering(self, force_empty):
        """
        Remove any ordering settings. If 'force_empty' is True, there will be
        no ordering in the resulting query (not even the model's default).
        """
        self.order_by = ()
        self.extra_order_by = ()
        if force_empty:
            self.default_ordering = False
    def add_ordering(self, *ordering):
        """
        Add items from the 'ordering' sequence to the query's "order by"
        clause. These items are either field names (not column names) --
        possibly with a direction prefix ('-' or '?') -- or OrderBy
        expressions.
    
        If 'ordering' is empty, clear all ordering from the query.
        """
        errors = []
        for item in ordering:
            if isinstance(item, str):
                if '.' in item:
                    warnings.warn(
                        'Passing column raw column aliases to order_by() is '
                        'deprecated. Wrap %r in a RawSQL expression before '
                        'passing it to order_by().' % item,
                        category=RemovedInDjango40Warning,
                        stacklevel=3,
                    )
                    continue
                if item == '?':
                    continue
                if item.startswith('-'):
                    item = item[1:]
                if item in self.annotations:
                    continue
                if self.extra and item in self.extra:
                    continue
                # names_to_path() validates the lookup. A descriptive
                # FieldError will be raise if it's not.
                self.names_to_path(item.split(LOOKUP_SEP), self.model._meta)
            elif not hasattr(item, 'resolve_expression'):
                errors.append(item)
            if getattr(item, 'contains_aggregate', False):
                raise FieldError(
                    'Using an aggregate in order_by() without also including '
                    'it in annotate() is not allowed: %s' % item
                )
        if errors:
            raise FieldError('Invalid order_by arguments: %s' % errors)
        if ordering:
            self.order_by += ordering
        else:
            self.default_ordering = False
  • • order_by做了克隆,返回了一个QuerySet的副本,然后它先清空了排序,然后再设置排序
  • • 看到add_ordering方法可以添加多个参数,所以就修改(正确写法):
  • userRank = User.objects.all().order_by('-rank', '-Taco', '-nowexp')[:50]

随机排序


  • • 随机排序就比较简单了,还是拿上面的排行做例子
  • - 方法一(我最常用的):
  • userRank = User.objects.all().order_by('?')[:50]
  • - 方法二:
    userRank = list(User.objects.all())
    random.shuffle(userRank)
    userRank = userRank[:50]

上一篇:AutoField报错

下一篇:Django变量名的坑

Comment

Message Board

编程导航

Django使用Less

美化后台管理Admin

FBV 和 CBV

SimpleUI后台导航栏报错

Django多条件查询

标签属性使用变量引发的BUG

auto_now=True引发的问题

图片上传后大小问题

Django版本查看和升级

values和values_list

过滤器linebreaksbr

拆分views文件

AutoField报错

order_by多条件和随机排序

Django变量名的坑

Copyright © 2020 芋圆社区

Powered by 浙ICP备2020039309号-1

此页面不支持夜间模式!

已进入夜间模式!

已进入普通模式!

搜索框不允许为空

签到成功!经验+5!芋圆币+2!

签到失败!今日已签到!

需要登录社区账号才可以进入!

复制成功
寄,页面未加载完成或页面无锚点