Django_QueryDict

 

介绍

class QueryDict(MultiValueDict):
    """
    A specialized MultiValueDict which represents a query string.

    A QueryDict can be used to represent GET or POST data. It subclasses
    MultiValueDict since keys in such data can be repeated, for instance
    in the data from a form with a <select multiple> field.

    By default QueryDicts are immutable, though the copy() method
    will always return a mutable copy.

    Both keys and values set on this class are converted from the given encoding
    (DEFAULT_CHARSET by default) to str.
    """

    # These are both reset in __init__, but is specified here at the class
    # level so that unpickling will have valid values
    _mutable = True
    _encoding = None

    def __init__(self, query_string=None, mutable=False, encoding=None):
        super().__init__()
        if not encoding:
            encoding = settings.DEFAULT_CHARSET
        self.encoding = encoding
        query_string = query_string or ''
        parse_qsl_kwargs = {
            'keep_blank_values': True,
            'fields_limit': settings.DATA_UPLOAD_MAX_NUMBER_FIELDS,
            'encoding': encoding,
        }
        if isinstance(query_string, bytes):
            # query_string normally contains URL-encoded data, a subset of ASCII.
            try:
                query_string = query_string.decode(encoding)
            except UnicodeDecodeError:
                # ... but some user agents are misbehaving :-(
                query_string = query_string.decode('iso-8859-1')
        for key, value in limited_parse_qsl(query_string, **parse_qsl_kwargs):
            self.appendlist(key, value)
        self._mutable = mutable

    @classmethod
    def fromkeys(cls, iterable, value='', mutable=False, encoding=None):
        """
        Return a new QueryDict with keys (may be repeated) from an iterable and
        values from value.
        """
        q = cls('', mutable=True, encoding=encoding)
        for key in iterable:
            q.appendlist(key, value)
        if not mutable:
            q._mutable = False
        return q

    @property
    def encoding(self):
        if self._encoding is None:
            self._encoding = settings.DEFAULT_CHARSET
        return self._encoding

    @encoding.setter
    def encoding(self, value):
        self._encoding = value

    def _assert_mutable(self):
        if not self._mutable:
            raise AttributeError("This QueryDict instance is immutable")

    def __setitem__(self, key, value):
        self._assert_mutable()
        key = bytes_to_text(key, self.encoding)
        value = bytes_to_text(value, self.encoding)
        super().__setitem__(key, value)

    def __delitem__(self, key):
        self._assert_mutable()
        super().__delitem__(key)

    def __copy__(self):
        result = self.__class__('', mutable=True, encoding=self.encoding)
        for key, value in self.lists():
            result.setlist(key, value)
        return result

    def __deepcopy__(self, memo):
        result = self.__class__('', mutable=True, encoding=self.encoding)
        memo[id(self)] = result
        for key, value in self.lists():
            result.setlist(copy.deepcopy(key, memo), copy.deepcopy(value, memo))
        return result

    def setlist(self, key, list_):
        self._assert_mutable()
        key = bytes_to_text(key, self.encoding)
        list_ = [bytes_to_text(elt, self.encoding) for elt in list_]
        super().setlist(key, list_)

    def setlistdefault(self, key, default_list=None):
        self._assert_mutable()
        return super().setlistdefault(key, default_list)

    def appendlist(self, key, value):
        self._assert_mutable()
        key = bytes_to_text(key, self.encoding)
        value = bytes_to_text(value, self.encoding)
        super().appendlist(key, value)

    def pop(self, key, *args):
        self._assert_mutable()
        return super().pop(key, *args)

    def popitem(self):
        self._assert_mutable()
        return super().popitem()

    def clear(self):
        self._assert_mutable()
        super().clear()

    def setdefault(self, key, default=None):
        self._assert_mutable()
        key = bytes_to_text(key, self.encoding)
        default = bytes_to_text(default, self.encoding)
        return super().setdefault(key, default)

    def copy(self):
        """Return a mutable copy of this object."""
        return self.__deepcopy__({})

    def urlencode(self, safe=None):
        """
        Return an encoded string of all query string arguments.

        `safe` specifies characters which don't require quoting, for example::

            >>> q = QueryDict(mutable=True)
            >>> q['next'] = '/a&b/'
            >>> q.urlencode()
            'next=%2Fa%26b%2F'
            >>> q.urlencode(safe='/')
            'next=/a%26b/'
        """
        output = []
        if safe:
            safe = force_bytes(safe, self.encoding)

            def encode(k, v):
                return '%s=%s' % ((quote(k, safe), quote(v, safe)))
        else:
            def encode(k, v):
                return urlencode({k: v})
        for k, list_ in self.lists():
            k = force_bytes(k, self.encoding)
            output.extend(encode(k, force_bytes(v, self.encoding))
                          for v in list_)
        return '&'.join(output)
QueryDict源码

 

使用示例

# coding:utf-8

if __name__ == "__main__":
    import os
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "first_review.settings")


    from django.http.request import QueryDict

    # 1.QueryDict.__init__(query_string=None, mutable=False, encoding=None)
    s = "a=1&b=2&c=abcd"
    qd = QueryDict(s,mutable=True)
    print(qd)  # <QueryDict: {'a': ['1'], 'b': ['2'], 'c': ['abcd']}>

    # 2.QueryDict.__getitem__(key)
    # 5.QueryDict.get(key, default)
    print(qd.get("a"))  # 1
    print(qd.__getitem__("b"))  # 2
    print(qd.get("z",1000000))  # 1000000
    print(qd["c"])  # abcd

    # 3.QueryDict.__setitem__(key, value)
    qd.__setitem__("d","44444")
    qd["e"] = [5]
    print(qd)  # <QueryDict: {'a': ['1'], 'b': ['2'], 'c': ['abcd'], 'd': ['44444'], 'e': [[5]]}>

    # 4.QueryDict.__contains__(key)
    print(qd.__contains__("d"))  # True
    print("e" in qd)  # True

    # 6.QueryDict.setdefault(key, default)
    print(qd.setdefault("a",10000000))  # 1
    print(qd.setdefault("f","ffff"))  # ffff
    print(qd)  # <QueryDict: {'a': ['1'], 'b': ['2'], 'c': ['abcd'], 'd': ['44444'], 'e': [[5]], 'f': ['ffff']}>

    # 7.QueryDict.update(other_dict)
    d = {"x":"xxxx","y":"yyyy","zzzzz":"zzz"}
    qd.update(d)
    print(qd)  # <QueryDict: {'a': ['1'], 'b': ['2'], 'c': ['abcd'], 'd': ['44444'], 'e': [[5]], 'f': ['ffff'], 'x': ['xxxx'], 'y': ['yyyy'], 'zzzzz': ['zzz']}>

    # 8.QueryDict.items()  # 生成器,python把python2的items和iteritems合并为items了,返回生成器
    # 9.QueryDict.iteritems()
    print(qd.items())  # <generator object MultiValueDict.items at 0x05029F60>
    print(list(qd.items()))  # [('a', '1'), ('b', '2'), ('c', 'abcd'), ('d', '44444'), ('e', [5]), ('f', 'ffff'), ('x', 'xxxx'), ('y', 'yyyy'), ('zzzzz', 'zzz')]

    # 11.QueryDict.values()
    # 12.QueryDict.itervalues()  Python3合并为values了,返回生成器
    print(qd.values())  # <generator object MultiValueDict.values at 0x05209F60>
    print(list(qd.values()))  # ['1', '2', 'abcd', '44444', [5], 'ffff', 'xxxx', 'yyyy', 'zzz']


    # 13.QueryDict.copy()  # 深拷贝,且为mutable=True的
    s = "a=1&a=1111&b=2&c=abcd"
    qd1 = QueryDict(s,mutable=False)
    qd2 = qd1.copy()
    print(qd1)  # <QueryDict: {'a': ['1', '1111'], 'b': ['2'], 'c': ['abcd']}>
    print(qd2)  # <QueryDict: {'a': ['1', '1111'], 'b': ['2'], 'c': ['abcd']}>
    print(qd2.setdefault("d",4))  # 4
    qd2.appendlist("a","aaaaaa")
    # qd1.setdefault("d",4)  # 出错,因为qd1是immutable的
    print(qd1)  # <QueryDict: {'a': ['1', '1111'], 'b': ['2'], 'c': ['abcd']}>
    print(qd2)  # <QueryDict: {'a': ['1', '1111', 'aaaaaa'], 'b': ['2'], 'c': ['abcd'], 'd': [4]}>

    # 14.QueryDict.getlist(key, default)
    print(qd2.getlist("a"))  # ['1', '1111', 'aaaaaa']

    # 15.QueryDict.setlist(key, list_)
    qd2.setlist("e",[5,5555])
    print(qd2)  # <QueryDict: {'a': ['1', '1111', 'aaaaaa'], 'b': ['2'], 'c': ['abcd'], 'd': [4], 'e': [5, 5555]}>

    # 16.QueryDict.appendlist(key, item)
    qd2.appendlist("e","eee")
    print(qd2)  #   # <QueryDict: {'a': ['1', '1111', 'aaaaaa'], 'b': ['2'], 'c': ['abcd'], 'd': [4], 'e': [5, 5555, 'eee']}>

    # 17.QueryDict.setlistdefault(key, default_list)  # 与setdefault类似
    qd2.setlistdefault("e",["new5555","xxx"])
    print(qd2)  # <QueryDict: {'a': ['1', '1111', 'aaaaaa'], 'b': ['2'], 'c': ['abcd'], 'd': [4], 'e': [5, 5555, 'eee']}>

    # 18.QueryDict.lists()
    print(qd2.lists()) # <dict_itemiterator object at 0x09BA20F0>
    print(list(qd2.lists()))  # [('a', ['1', '1111', 'aaaaaa']), ('b', ['2']), ('c', ['abcd']), ('d', [4]), ('e', [5, 5555, 'eee'])]

    # 19.QueryDict.pop(key)
    print(qd2.pop("e"))  # [5, 5555, 'eee']
    print(qd2)  # <QueryDict: {'a': ['1', '1111', 'aaaaaa'], 'b': ['2'], 'c': ['abcd'], 'd': [4]}>

    # 20.QueryDict.popitem()
    print(qd2.popitem())  # ('d', [4])
    print(qd2)  # <QueryDict: {'a': ['1', '1111', 'aaaaaa'], 'b': ['2'], 'c': ['abcd']}>

    # 21.QueryDict.dict()
    print(qd2.dict())  # {'a': 'aaaaaa', 'b': '2', 'c': 'abcd'}

    # 22.QueryDict.urlencode([safe])
    qd2.setdefault("z","/zzzzz/")
    print(qd2.urlencode())  # a=1&a=1111&a=aaaaaa&b=2&c=abcd&z=%2Fzzzzz%2F
    print(qd2.urlencode(safe="/"))  # a=1&a=1111&a=aaaaaa&b=2&c=abcd&z=/zzzzz/  # urlencode 可以传递不需要编码的字符。(这意味着要进行 url 编码)

QueryDict用法

 

posted @ 2018-09-14 15:39  fat39  阅读(453)  评论(0编辑  收藏  举报