1

kullanarak bir GET son nokta test ederken: https://stackoverflow.com/a/28429089MultiValueDictKeyError bu SO sonrası açıklanan yönteme aşağıdaki, ben <code>APIRequestFactory</code> kullanarak test çalışıyorum bir <code>GET</code> bitiş noktası var APIRequestFactory

İlk kapalı, biliyorum bu son nokta çalışır çünkü ben CURL aracılığıyla bir GET isteği gönderirken beklenen davranış olsun. Fabrikayı kullanarak bu isteği taklit yapmaya çalıştı

curl -X GET -H "Content-Type: application/json" -i -d "{\"cardinal_key\":12XXXX3, \"cardinal_type\":\"Npis\", \"terminal_type\":\"Deas\", \"candidate_count\":2}" http://127.0.0.1:8000/v1/ranked_results/ 
HTTP/1.0 200 OK 
Date: Mon, 28 Mar 2016 22:29:29 GMT 
Server: WSGIServer/0.2 CPython/3.4.3 
X-Frame-Options: SAMEORIGIN 
Allow: GET, HEAD, OPTIONS 
Vary: Accept, Cookie 
Content-Type: application/json 

{"npi":"12XXXX3","first_name":"XXXXXX","middle_name":null,"last_name":"XXXXXX","full_name":"XXXXX, XXXX XXXXX","link_candidates":{"FXXXXX9":0.9900022451986468,"BXXXXXXX3":0.8483023431385707}} 

Ancak, ben bir ValueError istisna (aşağıda tam iz) var: Bir sonraki düşünce şey olduğuydu

ValueError: need more than 1 value to unpack

from rest_framework.test import APIRequestFactory 
from linker.views import RankedResults 
factory = APIRequestFactory() 
options = {"cardinal_key":12XXXX3, "cardinal_type":"Npis", "terminal_type":"Deas", "candidate_count":2} 
request = factory.get('/v1/ranked_results/', json.dumps(options), content_type='application/json') 
view = RankedResults.as_view() 
response = view(request) 
çalışmaz, JSON olarak isteği göndermeye çalıştığım için isteği JSON olmadan yapmaya çalıştım ve sonra MultiValueDictKeyError:

from rest_framework.test import APIRequestFactory 
from linker.views import RankedResults 
factory = APIRequestFactory() 
options = {"cardinal_key":12XXXX3, "cardinal_type":"Npis", "terminal_type":"Deas", "candidate_count":2} 
request = factory.get('/v1/ranked_results/', options) 
view = RankedResults.as_view() 
response = view(request) 

MultiValueDictKeyError: "'cardinal_type'"

MultiValueDictKeyError istisna Benim anlayış anahtar sözlükte değilken o olur olmasıdır. Ayrıca, belgeler aynı anahtarla birden fazla değere sahip olduğunuzda MultiValueDict'un kullanıldığını söylüyor. Bunu neden görüyorum emin değilim çünkü bu, oluşturmaya çalıştığım istekte durum böyle değil.

Burada bir kayıp yaşıyorum - ne eksik?

görünüm:

class RankedResults(APIView): 
    def get(self, request): 
     cardinal_instance = apps.get_model('warehouse', request.data['cardinal_type']).objects.get(reference_key=request.data['cardinal_key']) 
     serializer = LinkModelSerializer(cardinal_instance, context=request.data) 
     return Response(serializer.data) 

serileştirici: Ben JSON isteği göndermek çalıştı durum için

class LinkModelSerializer(serializers.ModelSerializer): 
    link_candidates = serializers.SerializerMethodField('get_candidate_links') 

    def get_candidate_links(self, obj): 
     terminal = apps.get_model('warehouse', self.context['terminal_type']) 
     n = self.context['candidate_count'] 
     return dict(obj.top_n_candidates(terminal, n)) 

    class Meta: 
     model = warehouse.Npis 
     fields = ('npi', 'first_name', 'middle_name', 'last_name', 'full_name', 'link_candidates') 
     read_only_fields = ('link_candidates') 

İz: için

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-20-6b10ed2040c0> in <module>() 
     2 factory = APIRequestFactory() 
     3 options = {"cardinal_key":12XXXX3, "cardinal_type":"Npis", "terminal_type":"Deas", "candidate_count":2} 
----> 4 request = factory.get('/v1/ranked_results/', json.dumps(options), content_type='application/json') 
     5 view = RankedResults.as_view() 
     6 response = view(request) 

~/lib/python3.4/site-packages/rest_framework/test.py in get(self, path, data, **extra) 
    79  def get(self, path, data=None, **extra): 
    80   r = { 
---> 81    'QUERY_STRING': urlencode(data or {}, doseq=True), 
    82   } 
    83   # Fix to support old behavior where you have the arguments in the url 

~/lib/python3.4/site-packages/django/utils/http.py in urlencode(query, doseq) 
    94   [(force_str(k), 
    95   [force_str(i) for i in v] if isinstance(v, (list, tuple)) else force_str(v)) 
---> 96    for k, v in query], 
    97   doseq) 
    98 

~/lib/python3.4/site-packages/django/utils/http.py in <listcomp>(.0) 
    94   [(force_str(k), 
    95   [force_str(i) for i in v] if isinstance(v, (list, tuple)) else force_str(v)) 
---> 96    for k, v in query], 
    97   doseq) 
    98 

ValueError: need more than 1 value to unpack 

... son olarak iz JSON isteği olmadan denedim:

belgelenmesi itibaren
--------------------------------------------------------------------------- 
KeyError         Traceback (most recent call last) 
~/lib/python3.4/site-packages/django/utils/datastructures.py in __getitem__(self, key) 
    82   try: 
---> 83    list_ = super(MultiValueDict, self).__getitem__(key) 
    84   except KeyError: 

KeyError: 'cardinal_type' 

During handling of the above exception, another exception occurred: 

MultiValueDictKeyError     Traceback (most recent call last) 
<ipython-input-17-559ee170e692> in <module>() 
     4 request = factory.get('/v1/ranked_results/', options) 
     5 view = RankedResults.as_view() 
----> 6 response = view(request) 

~/lib/python3.4/site-packages/django/views/decorators/csrf.py in wrapped_view(*args, **kwargs) 
    56  # function. 
    57  def wrapped_view(*args, **kwargs): 
---> 58   return view_func(*args, **kwargs) 
    59  wrapped_view.csrf_exempt = True 
    60  return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view) 

~/lib/python3.4/site-packages/django/views/generic/base.py in view(request, *args, **kwargs) 
    66    self.args = args 
    67    self.kwargs = kwargs 
---> 68    return self.dispatch(request, *args, **kwargs) 
    69   view.view_class = cls 
    70   view.view_initkwargs = initkwargs 

~/lib/python3.4/site-packages/rest_framework/views.py in dispatch(self, request, *args, **kwargs) 
    464 
    465   except Exception as exc: 
--> 466    response = self.handle_exception(exc) 
    467 
    468   self.response = self.finalize_response(request, response, *args, **kwargs) 

~/lib/python3.4/site-packages/rest_framework/views.py in dispatch(self, request, *args, **kwargs) 
    461     handler = self.http_method_not_allowed 
    462 
--> 463    response = handler(request, *args, **kwargs) 
    464 
    465   except Exception as exc: 

~/views.py in get(self, request) 
    36 class RankedResults(APIView): 
    37  def get(self, request): 
---> 38   cardinal_instance = apps.get_model('warehouse', request.data['cardinal_type']).objects.get(reference_key=request.data['cardinal_key']) 
    39   serializer = LinkModelSerializer(cardinal_instance, context=request.data) 
    40   return Response(serializer.data) 

~/lib/python3.4/site-packages/django/utils/datastructures.py in __getitem__(self, key) 
    83    list_ = super(MultiValueDict, self).__getitem__(key) 
    84   except KeyError: 
---> 85    raise MultiValueDictKeyError(repr(key)) 
    86   try: 
    87    return list_[-1] 

MultiValueDictKeyError: "'cardinal_type'" 
+0

İlk yaklaşımı kullanarak 'get' yönteminde' request.data' yazdı mı? – AKS

+0

'------------------------------------------------ --------------------------- ' ' AttributeError Traceback (son çağrı son) ' ' () ------ 1 request.data' 'AttributeError: 'WSGIRequest' nesnesinin 'data' özelliği yoktur –

+0

Ancak 'request .__ dict__' dosyasına baktığımda sorgu dizesini görebilirim (bu bir alıntıdır): 'QUERY_STRING ':' cardinal_type = Npis & cardinal_key = 1XXXXXX3 & terminal_type = Deas & candidate_count = 2 ',' –

cevap

0

:

Bir POST, PUT veya PATCH istekte isteği gövdesine şey geçiyoruz zaman

request.data returns the parsed content of the request body. This is similar to the standard request.POST and request.FILES attributes...

Yani, request.data kullanılabilir.

Ama eğer bir GET yerine isteği yapıyoruz: GET istek sorgu dizesi almak için doğru yolu için

request = factory.get('/v1/ranked_results/', json.dumps(options), 
         content_type='application/json') 

request.query_params kullanıyor:

request.query_params is a more correctly named synonym for request.GET .

For clarity inside your code, we recommend using request.query_params instead of the Django's standard request.GET . Doing so will help keep your codebase more correct and obvious - any HTTP method type may include query parameters, not just GET requests.

Yani, mümkün olacaktır aşağıdaki gibi istediğinizi erişin:

cardinal_type = request.query_params['cardinal_type'] 
# and similarly others 
+0

Teşekkürler @AKS, yorumlarınıza teşekkürlerimi çözdüm, ancak tam olarak siz de yapmadım. tanımladı. "Veri" özniteliğinin "GET" isteğinde mevcut olmadığı, ancak "query_params" işlevini kullanma konusunda işe yaramadığı doğru. Sorgunun gövdesinde sorguyu göndermek yerine bir "POST" isteği kullandım ve 'request'de' data' özniteliğine erişebildim. –

+0

Sorgu paramları ile 'GET' isteğini kullandığınızda sorunun ne olduğunu söyleyebilir misiniz? – AKS

İlgili konular