Я получаю ошибку 400 Bad Request при использовании django-piston
Я пытаюсь использовать Piston для поддержки REST для Django.
Я выполнил свои обработчики в соответствии с предоставленной документацией.
Проблема в том, что я могу "читать" и "удалять" свой ресурс, но я не могу "создать" или "обновить".
Каждый раз, когда я нажимаю соответствующий api, я получаю ошибку 400 Bad request.
Я расширил класс Resource для csrf, используя этот общедоступный фрагмент кода:
class CsrfExemptResource(Resource):
"""A Custom Resource that is csrf exempt"""
def __init__(self, handler, authentication=None):
super(CsrfExemptResource, self).__init__(handler, authentication)
self.csrf_exempt = getattr(self.handler, 'csrf_exempt', True)
Мой класс (фрагмент кода) выглядит следующим образом:
user_resource = CsrfExemptResource(User)
class User(BaseHandler):
allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')
@require_extended
def create(self, request):
email = request.GET['email']
password = request.GET['password']
phoneNumber = request.GET['phoneNumber']
firstName = request.GET['firstName']
lastName = request.GET['lastName']
self.createNewUser(self, email,password,phoneNumber,firstName,lastName)
return rc.CREATED
Пожалуйста, дайте мне знать, как я могу заставить метод create работать с помощью операции POST?
Ответы
Ответ 1
Это происходит потому, что Piston не нравится, что ExtJS помещает "charset = UTF-8" в тип содержимого заголовка.
Легко фиксируется добавлением некоторого промежуточного программного обеспечения, чтобы сделать контент более удобным для Piston, создайте файл, называемый middleware.py в каталоге приложения:
class ContentTypeMiddleware(object):
def process_request(self, request):
if request.META['CONTENT_TYPE'] == 'application/x-www-form-urlencoded; charset=UTF-8':
request.META['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
return None
Затем просто добавьте это промежуточное программное обеспечение в свои settings.py:
MIDDLEWARE_CLASSES = (
'appname.middleware.ContentTypeMiddleware',
)
Ответ 2
Предлагаемые решения все еще не работали для меня (django 1.2.3/piston 0.2.2), поэтому я изменил решение joekrell, и это, наконец, работает (я использую только POST и PUT, но предположительно вы можете добавить другие глаголы к списку):
class ContentTypeMiddleware(object):
def process_request(self, request):
if request.method in ('POST', 'PUT'):
# dont break the multi-part headers !
if not 'boundary=' in request.META['CONTENT_TYPE']:
del request.META['CONTENT_TYPE']
с:
MIDDLEWARE_CLASSES = (
'appname.middleware.ContentTypeMiddleware',
)
Я не заметил никакого побочного эффекта, но я не могу обещать ему пуленепробиваемый.
Ответ 3
Я объединил некоторые из других людей и добавил поддержку любого типа контента, например json...
class ContentTypeMiddleware(object):
def process_request(self, request):
if request.method in ('POST', 'PUT') and request.META['CONTENT_TYPE'].count(";") > 0:
request.META['CONTENT_TYPE'] = [c.strip() for c in request.META['CONTENT_TYPE'].split(";") ][0]
return None
Ответ 4
Я думал, что решение Eric работает лучше всего, но затем столкнулось с проблемами при сохранении вещей в админ. Кажется, что эта настройка исправляет это, если кто-то еще сталкивается с ней:
class ContentTypeMiddleware(object):
def process_request(self, request):
if request.method in ('POST') and not 'boundary=' in request.META['CONTENT_TYPE']:
request.META['CONTENT_TYPE'] = [c.strip() for c in request.META['CONTENT_TYPE'].split(";") ][0]
return None
Ответ 5
В utils.py измените это.
def content_type(self):
"""
Returns the content type of the request in all cases where it is
different than a submitted form - application/x-www-form-urlencoded
"""
type_formencoded = "application/x-www-form-urlencoded"
ctype = self.request.META.get('CONTENT_TYPE', type_formencoded)
if ctype.strip().lower().find(type_formencoded) >= 0:
return None
return ctype
https://bitbucket.org/jespern/django-piston/issue/87/split-charset-encoding-form-content-type
Ответ 6
Это решение, которое сработало для меня после настройки:
class ContentTypeMiddleware(object):
def process_request(self, request):
if 'charset=UTF-8' in request.META['CONTENT_TYPE']:
request.META['CONTENT_TYPE'] = request.META['CONTENT_TYPE'].replace('; charset=UTF-8','')
return None
Ответ 7
У нас был ресурс, который просто обновлял временную метку на основе учетных данных запроса и PUT. Оказывается, что Piston не любит PUT без полезной нагрузки. Добавление пустой полезной нагрузки строки '' исправило ее.
Быстрый поиск в Google показывает, что другие системы, такие как Apache, могут не нравиться PUT без полезной нагрузки.