1. 程式人生 > 實用技巧 >JsonResponse物件和QueryDict物件

JsonResponse物件和QueryDict物件

JsonResponse物件

JsonResponse是HttpResponse的子類,專門用來生成JSON編碼的響應。class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None,**kwargs)

fromdjango.httpimportJsonResponse

response=JsonResponse({'foo':'bar'})
print(response.content)

b'{"foo":"bar"}'

這個類是HttpRespon的子類,它主要和父類的區別在於:

  1. 它的預設Content-Type
    被設定為:application/json
  2. 第一個引數,data應該是一個字典型別,第二個引數,關鍵字safe,當 safe 這個引數被設定為:False ,那data可以填入任何能被轉換為JSON格式的物件,比如list, tuple等。預設的safe引數是 True. 如果你傳入的data資料型別不是字典型別,那麼它就會丟擲 TypeError的異常。
response=JsonResponse([1,2,3],safe=False)
  1. json_dumps_params引數是一個字典,它將呼叫json.dumps()方法並將字典中的引數傳入給該方法。

  2. encoder預設為django.core.serializers.json.DjangoJSONEncoder

    ,用於序列化資料。如果需要使用不同的JSON 編碼器類,可以傳遞encoder引數給建構函式。response = JsonResponse(data, encoder=MyJSONEncoder)

#如果這樣返回,ajax還需要進行json解析
#views.py
returnHttpResponse(json.dumps({"msg":"ok!"}))

#index.html
vardata=json.parse(data)
console.log(data.msg);

使用HttpResponse物件來響應資料的時候,還可以通過content_type指定格式:

returnHttpResponse(json.dumps(data),content_type="application/json"
)
#如果這樣返回,兩邊都不需要進行json的序列化與反序列化,ajax接受的直接是一個物件

#views.py
fromdjango.httpimportJsonResponse
returnJsonResponse({"msg":"ok!"})

#index.html
console.log(data.msg);

QueryDict物件

在HttpRequest物件中,GET和POST屬性都是一個django.http.QueryDict的例項。也就是說你可以按本文下面提供的方法操作request.POST和request.GET。

request.POST或request.GET的QueryDict都是不可變,只讀的。如果要修改它,需要使用QueryDict.copy()方法,獲取它的一個拷貝,然後在這個拷貝上進行修改操作。

方法

QueryDict 實現了Python字典資料型別的所有標準方法,因為它是字典的子類

與字典資料型別的不同之處:

QueryDict例項化方法:

注意:QueryDict的鍵值是可以重複的!

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

如果需要例項化可以修改的物件,新增引數mutable=True。

classmethod QueryDict.fromkeys(iterable, value='', mutable=False, encoding=None)[source]

迴圈可迭代物件中的每個元素作為鍵值,並賦予同樣的值(來至value引數)。

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

追加內容,而不是更新並替換它們。

q=QueryDict('a=1',mutable=True)
q.update({'a':'2'})
q.getlist('a')
['1','2']
q['a']#returnsthelast
'2'
QueryDict.items()

類似dict.items(),如果有重複專案,返回最近的一個,而不是都返回:

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

類似dict.values(),但是隻返回最近的值:

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

使用copy.deepcopy()返回QueryDict物件的副本。 此副本是可變的。

QueryDict.getlist(key, default=None)

返回鍵對應的值列表。 如果該鍵不存在並且未提供預設值,則返回一個空列表。

QueryDict.setlist(key, list_)[source]

list_設定給定的鍵。

QueryDict.appendlist(key, item)[source]

將鍵追加到內部與鍵相關聯的列表中。

QueryDict.setdefault(key, default=None)[source]

類似dict.setdefault(),為某個鍵設定預設值。

QueryDict.setlistdefault(key, default_list=None)[source]

類似setdefault(),除了它需要的是一個值的列表而不是單個值。

QueryDict.lists()

類似items(),只是它將其中的每個鍵的值作為列表放在一起。 像這樣:

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

返回給定鍵的值的列表,並從QueryDict中移除該鍵。 如果鍵不存在,將引發KeyError。 像這樣:

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

刪除QueryDict任意一個鍵,並返回二值元組,包含鍵和鍵的所有值的列表。在一個空的字典上呼叫時將引發KeyError。 像這樣:

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

將QueryDict轉換為Python的字典資料型別,並返回該字典。

如果出現重複的鍵,則將所有的值打包成一個列表,最為新字典中鍵的值。

q=QueryDict('a=1&a=3&a=5')
q.dict()
{'a':[1,3,5,]}
QueryDict.urlencode(safe=None)[source]

已url的編碼格式返回資料字串。 像這樣:

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

使用safe引數傳遞不需要編碼的字元。 像這樣:

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

StreamingHttpResponse類

StreamingHttpResponse類被用來從Django響應一個流式物件到瀏覽器。如果生成的響應太長或者是佔用的記憶體較大,這麼做可能更有效率。 例如,它對於生成大型的CSV檔案非常有用。

StreamingHttpResponse不是HttpResponse的衍生類(子類),因為它實現了完全不同的應用程式介面。但是,除了幾個明顯不同的地方,兩者幾乎完全相同。

`get_object_or_404()`

get_object_or_404(klass, *args,* *kwargs)[source]

常用於查詢某個物件,找到了則進行下一步處理,如果未找到則給使用者返回404頁面。

在後臺,Django其實是呼叫了模型管理器的get()方法,只會返回一個物件。不同的是,如果get()發生異常,會引發Http404異常,從而返回404頁面,而不是模型的DoesNotExist異常。

必需引數

  • klass:要獲取的物件的Model類名或者Queryset等;
  • **kwargs:查詢的引數,格式應該可以被get()接受。

範例:

1.從MyModel中使用主鍵1來獲取物件:

fromdjango.shortcutsimportget_object_or_404

defmy_view(request):
my_object=get_object_or_404(MyModel,pk=1)

這個示例等同於:

fromdjango.httpimportHttp404

defmy_view(request):
try:
my_object=MyModel.objects.get(pk=1)
exceptMyModel.DoesNotExist:
raiseHttp404("NoMyModelmatchesthegivenquery.")

2.除了傳遞Model名稱,還可以傳遞一個QuerySet例項:

queryset=Book.objects.filter(title__startswith='M')
get_object_or_404(queryset,pk=1)

上面的示例不夠簡潔,因為它等同於:

get_object_or_404(Book,title__startswith='M',pk=1)

但是如果queryset來自其它地方,它就會很有用了。

3.還可以使用Manager。 如果你自定義了管理器,這將很有用:

get_object_or_404(Book.dahl_objects,title='Matilda')

4.還可以使用related managers:

author=Author.objects.get(name='RoaldDahl')
get_object_or_404(author.book_set,title='Matilda')

與get()一樣,如果找到多個物件將引發一個MultipleObjectsReturned異常。

`get_list_or_404()`

get_list_or_404(klass, args, *kwargs)[source]

這其實就是get_object_or_404多值獲取版本。

在後臺,返回一個給定模型管理器上filter()的結果,並將結果對映為一個列表,如果結果為空則彈出Http404異常。

必需引數

  • klass:獲取該列表的一個Model、Manager或QuerySet例項。
  • **kwargs:查詢的引數,格式應該可以被filter()接受。

範例:

下面的示例從MyModel中獲取所有釋出出來的物件:

fromdjango.shortcutsimportget_list_or_404

defmy_view(request):
my_objects=get_list_or_404(MyModel,published=True)

這個示例等同於:

fromdjango.httpimportHttp404

defmy_view(request):
my_objects=list(MyModel.objects.filter(published=True))
ifnotmy_objects:
raiseHttp404("NoMyModelmatchesthegivenquery.")