IT/WEB

[Django] Querydict 객체

개발자 두더지 2020. 9. 17. 16:14
728x90

 HttpRequest 객체에서 GET과 POST 속성은 django.http.QueryDict의 인스턴스이다. QueryDict은 사전형 타입의 클래스로 같은 키에 대해 복수의 값을 갖도록 커스터마이즈 할 수 있다. 이것은 HTML의 form 요소에서는 예를 들어 <select multiple="multiple">과 같이 같은 키에 대해서 복수의 값을 전달해야할 필요가 있기 때문이다.

 QueryDict 인스턴스는 copy()를  만들지 않는 한 불변(immutable)이다. 즉 request.POST나 request.GET의 속성을 직접 변경할 수 없다는 것이다. 

 

Methods


 QueryDict는 사전형의 서브 클래스이므로, 모두 표준적인 사전형의 메소드로 정의되어 있다. 그러나 아래와 같이 다른 점이 있다.

QueryDict.__init__(query_string=None, mutable=False, encoding=None)

 Query객체의 인스턴스화는 query_string에 기반한다.

>>> QueryDict('a=1&a=2&c=3')
<QueryDict: {'a': ['1', '2'], 'c': ['3']}>

 만약 query_string이 전달되지 않으면, QueryDict의 결과는 비어 있을 것이다 (아무런 키와 값을 가지지 않는). 대부분의 QueryDict, 특히 request.POST 및 request.GET에서의 QueryDict는 변경할 수 없다(immutable). 직접 인스턴스화하는 경우, mutable=True to its __init__()를 지나치게하여 mutable하게 만들 수 있다. 키와 값 모두 설정하는 문자열은 인코딩에서 str로 변환된다. 인코딩이 설정되어 있지 않다면 기본값은 DEFAULT_CHARSET이 된다.

classmethod QueryDict.fromkeys(iterable, vlaue=", mutable=False, encoding=None)

 iterable의 키와 각 값이 vlaue와 같은 새로운 QueryDict를 생성한다. 예를 들면 다음과 같다:

>>> QueryDict.fromkeys(['a', 'a', 'b'], value='val')
<QueryDict: {'a': ['val', 'val'], 'b': ['val']}>

QueryDict.__getitem__(key)

 지정된 키에 대해 값을 돌려준다. 하나의 키에 복수의 값이 존재하는 경우, __getitem__()은 리스트의 끝에 값을 돌려준다. 키에 대응하는 값이 없으면 django.utils.datastructure.MutivalueDictKeyError 에러가 보여진다. (이러한 예외는 KeyError의 서브클래스이므로, 유심히 보면 KeyError를 포착할 수 있을 것이다.)

QueryDict.__setitem__(key, value)

 지정된 키에 대한 값을 [value] (value라는 값이 1개 들어 있는 리스트)로 한다. 다른 함수와 동일하게 이 메소드를 호출하는 것은 (copy()를 사용해 생성한 객체와 같이) 변환 가능한 QueryDict뿐이다.

QueryDict.get(key, default = None)

 위의 __getitem__()와 같은 로직이지만 키에 대응하는 값이 없을 때 기본값을 돌려주는 후크가 있다. 

QueryDict.update(other_dict)

 QueryDict 혹은 표준 사전형을 인수로 취한다. 표준 사전형의 update()메소드와 동일하지만, 현재의 값을 대체하지 않고 현재 값을 리스트에 추가한다. 예를 들어:

>>> q = QueryDict('a=1', mutable=True)
>>> q.update({'a': '2'})
>>> q.getlist('a')
['1', '2']
>>> q['a'] # returns the last
'2'

QueryDict.items()

dict.items()메소드와 같지만, __getitem()__와 같이 마지막 값을 돌려주는 로직을 사용한다. 예를 들어 :

>>> q = QueryDict('a=1&a=2&a=3')
>>> q.items()
[('a', '3')]

QueryDict.vlaues()

dict.values()와 같지만, __getitem()__와 같이 마지막의 값을 돌려주는 로직을 사용한다. 예를 들어.

>>> q = QueryDict('a=1&a=2&a=3')
>>> q.values()
['3']

더욱이, QueryDict에는 아래와 같은 메소드들이 있다.

QueryDict.copy()

Python 표준 라이브러리의 copy.deepcopy()를 사용하여 객체의 복제를 생성하여 리턴한다. 복제는 변경가능하므로 값을 변경할 수 있다.

QueryDitct.getlist(key, defalut=None)

요청된 키에 대해 Python의 리스트형으로 리턴해준다. 키에 대응하는 값을 없으면 공백의 리스트가 반환된다. 이 메소드는 확실히 어떠한 리스트든 리턴해준다고 할 수 있다.

QueryDict.setlist(key, list_)

키에 대해 list_를 대응 시켜준다 (__setitem__()과 다르다).

QueryDict.appendlist(key, item)

키와 연관되어 있는 내부 리스트를 요소에 추가해준다. 

QueryDict.setlistdefault(key, default_list=None)

setdefault와 닮았지만, 단일 값이 아닌 값의 리스트를 인수로 취한다.

QueryDict.lists()

items()와 비슷하지만, 모든 값을 리스트로 돌려준다. 예를 들어 :

>>> q = QueryDict('a=1&a=2&a=3')
>>> q.lists()
[('a', ['1', '2', '3'])]

QueryDict.pop(key)

주어진 키에 대한 값의 리스트를 리턴하고 사전에서 삭제한다. 만약 키가 존재하지 않으면 KeyError가 발생한다. 예를 들어:

>>> q = QueryDict('a=1&a=2&a=3', mutable=True)
>>> q.pop('a')
['1', '2', '3']

QueryDict.popitem()

사전에서 임의의 구성원을 삭제한다. 그리고 키와 키의 모든 값의 리스트를 포함하는 두 개의 값을 튜플형식으로 반환한다. 빈 사전형을 호출하면 KeyError가 발생한다. 예를 들어:

>>> q = QueryDict('a=1&a=2&a=3', mutable=True)
>>> q.popitem()
('a', ['1', '2', '3'])

QueryDict.dict()

QueryDict의 사전형 표현을 리턴한다. QueryDict의 모든 (key,list)쌍에 대해 dict은 (key, item)을 가지고 있다. 여기서 리스트의 요소 중 하나인 item은 QueryDict.__getitem__()과 동일한 로직을 가지고 있다. 

>>> q = QueryDict('a=1&a=3&a=5')
>>> q.dict()
{'a': '5'}

QueryDict.urlencode(safe=None)

데이터를 쿼리문자열 형식으로 바꾼 문자열을 리턴한다. 예를 들어 "a=2&b=3&b=5"와 같이 리턴한다.

>>> q = QueryDict('a=2&b=3&b=5')
>>> q.urlencode()
'a=2&b=3&b=5'

 safe에 encoding에 포함시키지 않을 문자를 지정할 수 있다. 예를 들어:

>>> q = QueryDict(mutable=True)
>>> q['next'] = '/a&b/'
>>> q.urlencode(safe='/')
'next=/a%26b/'

참고자료

djangoproject.jp/doc/ja/1.0/ref/request-response.html

docs.djangoproject.com/en/3.1/ref/request-response/#django.http.QueryDict.__getitem__

728x90