заморозка пункта
Django==1.6.2
Markdown==2.3.1
South==0.8.4
argparse==1.2.1
django-filter==0.7
django-guardian==1.1.1
django-oauth-plus==2.2.3
django-registration==1.0
djangorestframework==2.3.11
httplib2==0.8
ipdb==0.8
ipython==2.0.0
oauth2==1.5.211
psycopg2==2.5.2
wsgiref==0.1.2
Запрос:
PUT /api/v1/place/14/ BODY: name=NEW3&latitude=55.74659&longitude=37.626484
Ответ:
{"detail": "Invalid signature. Expected signature base string: PUT&http%3A%2F%2Fyavezu.com%3A8005%2Fapi%2Fv1%2Fplace%2F14%2F&oauth_consumer_key%3Daa68ec89fc944c60880f59e18dc6e982%26oauth_nonce%3D-4587244018477714645%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1398769361%26oauth_token%3D03cd9df066244aa2884a5508ff0d9fff%26oauth_version%3D1.0"}
Как видите, PUT-параметры не включены в базовую строку.
Я немного покопался в коде и нашел две причины этому.
- PUT-параметры не поддерживаются в oauth_provider
см. строку:
if request.method == "POST" and request.META.get('CONTENT_TYPE') == "application/x-www-form-urlencoded":
oauth_provider.utils
def get_oauth_request(request):
""" Converts a Django request object into an `oauth2.Request` object. """
# Django converts Authorization header in HTTP_AUTHORIZATION
# Warning: it doesn't happen in tests but it's useful, do not remove!
auth_header = {}
if 'Authorization' in request.META:
auth_header = {'Authorization': request.META['Authorization']}
elif 'HTTP_AUTHORIZATION' in request.META:
auth_header = {'Authorization': request.META['HTTP_AUTHORIZATION']}
# include POST parameters if content type is
# 'application/x-www-form-urlencoded' and request
# see: http://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
parameters = {}
if request.method == "POST" and request.META.get('CONTENT_TYPE') == "application/x-www-form-urlencoded":
parameters = dict((k, v.encode('utf-8')) for (k, v) in request.POST.iteritems())
absolute_uri = request.build_absolute_uri(request.path)
if "HTTP_X_FORWARDED_PROTO" in request.META:
scheme = request.META["HTTP_X_FORWARDED_PROTO"]
absolute_uri = urlunparse((scheme, ) + urlparse(absolute_uri)[1:])
return oauth.Request.from_request(request.method,
absolute_uri,
headers=auth_header,
parameters=parameters,
query_string=request.META.get('QUERY_STRING', '')
)
PUT-параметры не поддерживаются в классах
django.core.handlers.wsgi.WSGIRequest
иdjango.http.request.HttpRequest
:def _load_post_and_files(self): """Заполнить файлы self._post и self._files, если тип содержимого является типом формы""" if self.method != 'POST': self._post, self._files = QueryDict(' ', encoding=self._encoding), MultiValueDict() возвращает...
Интересно, как Django REST Framework может предоставить RESTful API поверх Django без поддержки PUT-параметров? Что я делаю неправильно? POST-запросы работают нормально.
Я также задал этот вопрос в группах Google: https://groups.google.com/forum/m/?fromgroups#!topic/django-rest-framework/679fOg0QpzI