现有剧本编写系统中:
线上环境:一级topic没有按照字母排序,但是二级按照字母排序了:
本地环境:一级topic和二级,都按照字母排序了:
而代码本身是一样的,所以很是奇怪。
去看了看
前端web的代码:
export async function queryTopics(params) {
return request(`${apiPrefix}/topics/?${stringify(params)}`, {
headers: constructHeaders(),
});
}
和后端的代码:
class TopicViewSet(viewsets.ModelViewSet):
"""
topic 列表/新增/更新/删除。标准 viewsets,没有任何复写方法
"""
queryset = Topic.objects.all().filter(type=’sectorTopic’).order_by(‘name’)
serializer_class = TopicSerializer
permission_classes = (IsAuthenticated, IsUserScriptFunctionGroup)
def list(self, request, *args, **kwargs):
topic_queryset = Topic.objects.all().filter(type=’sectorTopic’).order_by(‘name’)
topic_result = {}
for i in topic_queryset:
second_level_keyword_ids = list(KeywordRel.objects.filter(keyword1=i, type=0).values_list(‘keyword2’, flat=True))
second_level_keyword_names = list(Topic.objects.filter(pk__in=second_level_keyword_ids, type=’topic’).order_by(‘name’).values_list(‘name’, flat=True))
topic_result[i.name] = second_level_keyword_names
return Response(topic_result, status=status.HTTP_200_OK)
感觉像是:
本地代码是python 3.6的,dict是默认有序的
而线上环境python是3.4的(用的pipenv管理虚拟环境,没法完全复制环境,只能用服务器中已有的python 3-》Python 3.4),dict默认是无序的
导致后端返回给的前端dict中一级topic是无序的
所以去看看:
python dict 有序列表
python dict order 3.6
好像换用OrderedDict,就可以确保是有序的了?
python — 有序字典, 有序字典的排序 – CSDN博客
Python 有序字典简介 – Python提高班 – SegmentFault 思否
Are dictionaries ordered in Python 3.6+? – Stack Overflow
也建议:如果确保有序,换用OrderedDict
python 3.6中是实现细节保证有序
而3.7中,变成规范,强制要求有序了
[Python-Dev] Python 3.6 dict becomes compact and gets a private version; and keywords become ordered
python OrderedDict
8.3. collections — High-performance container datatypes — Python 2.7.15 documentation
8.3. collections — Container datatypes — Python 3.7.0 documentation
不可不知的Python模块: collections | Piglei
【总结】
此处本地环境是Python 3.6:dict内部CPython实现已经是有序列表,所以改动之前,本地已经是有序了。
而在线环境是Python 3.4,dict的实现还是之前的无序的。
Python 3.7之后,官网已经把dict的有序列为内置特性了
但是为了保持和之前代码逻辑统一,想要确保是有序的话,还是建议用:OrderedDict
所以去改为:
from collections import OrderedDict
# topic_result = {}
topic_result = OrderedDict()
即可使得此处一级topic的列表的列表保持之前从mysql中查询且加了order_by name参数的,已经根据字母排序的列表里了: