2010-12-27 13 views
11

Estoy intentando utilizar Piston para proporcionar soporte REST a Django. Implementé mis controladores según la documentación provista. El problema es que puedo "leer" y "eliminar" mi recurso, pero no puedo "crear" o "actualizar". Cada vez que pulso la api correspondiente obtengo un error de 400 Bad request.Recibo un error de 400 solicitudes incorrectas durante el uso de django-piston

He ampliado la clase de recursos para csrf mediante el uso de este fragmento de código comúnmente disponibles:

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) 

Mi clase (fragmento de código) se parece a esto:

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 

Por favor, hágamelo saber cómo puede obtengo el método create para trabajar usando la operación POST?

+0

Bien, comenté "django.middleware.csrf.CsrfViewMiddleware" del archivo de configuración en lugar de usar la extensión de la clase de recursos. Todavía veo el problema aunque – Cheezo

+0

¿Cómo está intentando la operación HTTP "PUT" o "POST" que corresponde a "crear" o "actualizar"? ¿Cómo sabe que este código del lado del cliente está creando una solicitud HTTP correcta y válida? –

+0

Para el POST, uso un cliente de reposo WizTools.org desde el cual puedo crear explícitamente una solicitud de POST. Por lo menos, estoy seguro de que la solicitud se está procesando y eso es suficiente, supongo. – Cheezo

Respuesta

1

En utils.py, cambie esto.

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

10

Esto sucede porque Pistón no le gusta el hecho de que ExtJS está poniendo "charset = UTF-8" en el tipo de contenido de la cabecera.

puede arreglar fácilmente añadiendo un poco de middleware para hacer el tipo de contenido un poco más amigable pistón, crear un archivo llamado middleware.py en su aplicación del directorio de base:

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 

A continuación, basta con incluir este middleware en la configuración de .py:

MIDDLEWARE_CLASSES = (
    'appname.middleware.ContentTypeMiddleware', 
) 
7

soluciones propuestas aún no funcionaba para mí (Django 1.2.3/0.2.2 pistón), así que hemos ajustado joekrell solución y esto finalmente funciona (sólo estoy usando POST y PUT, pero presumiblemente puede agregar otros verbos a la lista):

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'] 

con:

MIDDLEWARE_CLASSES = (
'appname.middleware.ContentTypeMiddleware', 
) 

no he notado ningún efecto secundario, pero no puedo prometer que es a prueba de balas.

+2

Sí, su solución también funcionó para mí (Django 1.3, Piston 0.2.2). En general, parece que Piston se convirtió en un abandono: no se actualizó en mucho tiempo. –

4

he combinado algunas de lo que otras personas han dicho, y ha añadido soporte para cualquier tipo de contenido, por ejemplo 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 
+0

Esta fue la mejor solución. Gracias. – GivP

+0

usando esto para POST rompió otras cosas pero solucionó mis problemas cuando se usa solo para PUT –

4

pensé solución de Eric trabajó la mejor, pero luego tuvo problemas al guardar cosas en admin. Este truco parece solucionarlo si alguien viene a través de ella:

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 
1

Esta es la solución que funcionó para mí, después de un pellizco:

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 
0

Tuvimos un recurso que fue simplemente actualizando una marca de tiempo basada en las credenciales de solicitud y PUT. Resulta que a Piston no le gusta PUT sin una carga útil. Agregar una carga útil de cadena vacía '' lo solucionó.

Una búsqueda rápida en Google indica que otros sistemas como Apache pueden no gustar también PUT sin una carga útil.

Cuestiones relacionadas