Я получаю ошибку 400 Bad Request при использовании django-поршня - PullRequest
11 голосов
/ 27 декабря 2010

Я пытаюсь использовать Piston для поддержки REST для Django.Я реализовал свои обработчики согласно предоставленной документации.Проблема в том, что я могу «прочитать» и «удалить» свой ресурс, но я не могу «создать» или «обновить».Каждый раз, когда я нажимаю соответствующий API, я получаю ошибку 400 Bad request.

Я расширяю класс ресурсов для 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?

Ответы [ 7 ]

10 голосов
/ 25 марта 2011

Это происходит потому, что Piston не нравится тот факт, что ExtJS помещает "charset = UTF-8" в тип содержимого заголовка.

Легко исправляется путем добавления некоторого промежуточного программного обеспечения, чтобы сделать тип контента немного более дружественным к поршню, создайте файл 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

Затем просто включите это промежуточное программное обеспечение в свои настройки.py:

MIDDLEWARE_CLASSES = (
    'appname.middleware.ContentTypeMiddleware',
)
7 голосов
/ 09 апреля 2011

Предлагаемые решения все еще не работали для меня (django 1.2.3 / поршень 0.2.2), поэтому я настроил решение Джокрелла, и это наконец работает (я использую только 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',
)

Я не заметил никаких побочных эффектов, но не могу обещать, что это пуленепробиваемый.

4 голосов
/ 05 октября 2011

Я думал, что решение Эрика сработало лучше, но потом столкнулся с проблемами при сохранении вещей в админке. Эта настройка, кажется, исправляет это, если кто-то еще сталкивается с этим:

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
4 голосов
/ 24 августа 2011

Я объединил кое-что из того, что сказали другие, и добавил поддержку для любого типа контента, например, 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
1 голос
/ 23 октября 2013

Это решение, которое сработало для меня после настройки:

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
1 голос
/ 21 января 2011

В 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

0 голосов
/ 25 октября 2014

У нас был ресурс, который просто обновлял метку времени на основе учетных данных запроса и PUT.Оказывается, Piston не любит PUT без полезной нагрузки.Добавление пустой строки полезных данных '' исправило это.

Быстрый поиск в Google показывает, что другие системы, такие как Apache, могут не любить PUT и без полезной нагрузки.

...