我可以使Django QueryDict保留顺序吗? [英] Can I make Django QueryDict preserve ordering?
问题描述
是否可以使Django的QueryDict保留原始查询字符串的顺序?
Is it possible to to make Django's QueryDict preserve the ordering from the original query string?
>>> from django.http import QueryDict
>>> q = QueryDict(u'x=foo³&y=bar(potato),z=hello world')
>>> q.urlencode(safe='()')
u'y=bar(potato)%2Cz%3Dhello%20world&x=foo%C2%B3'
推荐答案
QueryDict
类基于 MultiValueDict
基于常规的类python dict
,这是您所知道的无序集合。
QueryDict
class is based on MultiValueDict
class that is based on regular python dict
, which is an unordered collection as you know.
根据源代码, QueryDict
内部使用 urlparse.parse_qsl()
方法保留查询参数的顺序,并输出一个列表元组:
According to the source code, QueryDict
internally uses urlparse.parse_qsl()
method, which preserves the order of query parameters, outputs a list of tuples:
>>> from urlparse import parse_qsl
>>> parse_qsl('x=foo³&y=bar(potato),z=hello world')
[('x', 'foo\xc2\xb3'), ('y', 'bar(potato),z=hello world')]
您可以做的就是使用键的顺序由 parse_qsl()
给出以进行排序:
What you can do, is to use the order of keys given by the parse_qsl()
for sorting:
>>> order = [key for key, _ in parse_qsl('x=foo³&y=bar(potato),z=hello world')]
>>> order
['x', 'y']
然后,子类 QueryDict
并覆盖 urlencode()
中使用的 lists()
方法:
Then, subclass QueryDict
and override lists()
method used in urlencode()
:
>>> class MyQueryDict(QueryDict):
... def __init__(self, query_string, mutable=False, encoding=None, order=None):
... super(MyQueryDict, self).__init__(query_string, mutable=False, encoding=None)
... self.order = order
... def lists(self):
... return [(key, self.getlist(key)) for key in self.order]
...
>>> q = MyQueryDict(u'x=foo³&y=bar(potato),z=hello world', order=order)
>>> q.urlencode(safe='()')
u'x=foo%C2%B3&y=bar(potato)%2Cz%3Dhello%20world'
这种方法有点丑陋,可能需要进一步改进,但希望至少它能使您对正在发生的事情以及可以采取的措施有所了解
The approach is a bit ugly and may need further improvement, but hope at least it'll give you an idea of what is happening and what you can do about it.
这篇关于我可以使Django QueryDict保留顺序吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!