简体   繁体   English

Django order_by 不是查询结果的排序

[英]Django order_by is not ordering results of query

Django not ordering results by date. Django 未按日期排序结果。 Am using Django-Rest-Framework to create API for app initially had a filter by on the query and after reading similar issues where people faced same problem when combining order_by and filter I removed the filter and manually filtered using a for loop but still keep getting the same results.我正在使用 Django-Rest-Framework 创建 API 应用程序最初在查询中有一个过滤器,在阅读了类似的问题后,人们在结合 order_by 和过滤器时遇到了同样的问题,我删除了过滤器并使用 for 循环手动过滤,但仍然得到相同的结果。

Initially query was:最初查询是:

progresslogs = ProgressLog.objects.filter(user__userprofile__coach=request.user).order_by('-date')

But reading similar issues I changed the query and filtered manually think there is an issue with using filter and order by together but am still getting the results out of order:但是阅读类似的问题我改变了查询并手动过滤认为一起使用过滤器和排序有问题但我仍然得到乱序的结果:

class ProgressLogAPI(APIView):
    def get(self, request: Request, format=None):
        if request.user.is_authenticated:
            if request.user.is_staff:
                logger.info('API: Staff {} fetched progress logs'.format(request.user.id))
                progresslogs = ProgressLog.objects.order_by('-date')
                # Below loop added to manually filter results
                filteredlogs = []
                for progress in progresslogs:
                    if progress.user.userprofile.coach == request.user:
                        filteredlogs.append(progress)

                serializer = ProgressLogSerializer(filteredlogs, many=True)
                return Response(data=serializer.data)

But in each case the results are coming out of order, wondering is this some bug in Django, I suppose could probably sort the results manually but am thinking this would drastically increase the time for the API call to get the results so don't really want to do this.但在每种情况下,结果都是乱序的,想知道这是 Django 中的一些错误,我想可能可以手动对结果进行排序,但我认为这会大大增加 API 调用获取结果的时间,所以不要真的想这样做。

For reference the first 3 result from the API call are below with non applicable data replaced by aa '?'作为参考,下面是 API 调用的前 3 个结果,其中不适用的数据被替换为 aa '?' but can clearly from the date values that there not ordered at all:但可以从根本没有订购的日期值中清楚地看出:

[
  {
    "id":?,
    "user":?,
    "front_pic":"?",
    "side_pic":"?",
    "back_pic":"?",
    "weight":"?",
    "date":"2022-04-30",
    "bicep":null,
    "chest":null,
    "legs":null,
    "waist":null,
    "body_fat":null
  },
  {
     "id":?,
     "user":?,
    "front_pic":"?",
    "side_pic":"?",
    "back_pic":"?",
    "weight":"?",
    "date":"2022-03-27",
    "bicep":null,
    "chest":null,
    "legs":null,
    "waist":null,
    "body_fat":null
  },
  {
    "id":?,
    "user":?,
    "front_pic":"?",
    "side_pic":"?",
    "back_pic":"?",
    "weight":"?",
    "date":"2022-05-22",
    "bicep":null,
    "chest":null,
    "legs":null,
    "waist":null,
    "body_fat":null
  },
  ...
]

Django version on the server is 3.2.13 and python version is 3.9 .服务器上的 Django 版本是3.2.13和 python 版本是3.9

EDIT: As requested here is the model and serialised:编辑:这里要求的是 model 和序列化:

Model: Model:

class ProgressLog(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    front_pic = models.ImageField(upload_to='progress_front', blank=True)
    side_pic = models.ImageField(upload_to='progress_side', blank=True)
    back_pic = models.ImageField(upload_to='progress_back', blank=True)
    weight = models.DecimalField(blank=True, decimal_places=1, max_digits=6)
    date = models.DateField(default=get_date)
    body_fat = models.DecimalField(blank=True, decimal_places=1, max_digits=4, null=True)
    waist = models.IntegerField(blank=True, null=True)
    bicep = models.IntegerField(blank=True, null=True)
    chest = models.IntegerField(blank=True, null=True)
    legs = models.IntegerField(blank=True, null=True)

    def __str__(self):
        return '{} | {}'.format(self.user.username, self.date)

Serializer:序列化器:

class ProgressLogSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProgressLog
        fields = ['id', 'user', 'front_pic', 'side_pic', 'back_pic', 'weight', 'date', 'bicep', 'chest', 'legs', 'waist',
                  'body_fat']

Since posting the question last night I have tried updating Django to version 4.0.2 in case there was any bugs in the specific version of Django causing this, but results are still no ordered by date field.自从昨晚发布问题以来,我尝试将 Django 更新到版本4.0.2 ,以防 Django 的特定版本中存在任何错误导致此问题,但结果仍然没有按日期字段排序。

Also checked by querying in the Django shell `python manage.py shell' on the server, and in this case the results are in order:还通过在服务器上的 Django shell `python manage.py shell' 中查询进行检查,本例中的结果是有序的:

>>> from progress_logger.models import ProgressLog
>>> ProgressLog.objects.all().order_by('-date')[:3]
<QuerySet [<ProgressLog: ? | 2022-05-24>, <ProgressLog: ? | 2022-05-23>, <ProgressLog: ? | 2022-05-23>]>

Haven't been able to solve it the way I wanted but using ListViewAPI instead seems to have fixed it, guessing the problem might be related to Django-rest-framework as the results from the interactive shell where as expected:无法按照我想要的方式解决它,但使用 ListViewAPI 似乎已经解决了它,猜测问题可能与 Django-rest-framework 有关,因为交互式 shell 的结果如预期的那样:

class ProgressLogAPI(ListAPIView):
    permission_classes = [IsAdminUser]
    queryset = ProgressLog.objects.filter(user__userprofile__coach=request.user).order_by('-date')
    serializer_class = ProgressLogSerializer

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM