Search code examples
djangotastypie

Django TastyPie 0.10.0 not accepting POST request


I can't seem to get TastyPie to accept a POST request, made via Ajax or not. I get an error:

The format indicated 'multipart/form-data' had no available deserialization method. Please check your formats and content_types on your Serializer.

My model resource is:

class ClippedCouponResource(ModelResource):
    class Meta:
        queryset = ClippedCoupon.objects.all()
        allowed_methods = ['get', 'post']
        serializers = UrlencodeSerializer()
        authentication = DjangoCookieBasicAuthentication()
        authorization = DjangoAuthorization()
        default_format = 'application/json'

My serializer is:

from urlparse import urlparse

from tastypie.serializers import Serializer


class UrlencodeSerializer(Serializer):
    formats = ['json', 'jsonp', 'xml', 'yaml', 'html', 'plist', 'urlencode']
    content_types = {
        'json': 'application/json',
        'jsonp': 'text/javascript',
        'xml': 'application/xml',
        'yaml': 'text/yaml',
        'html': 'text/html',
        'plist': 'application/x-plist',
        'urlencode': 'application/x-www-form-urlencoded',
    }

    def from_urlencode(self, data, options=None):
        """ handles basic formencoded url posts """
        qs = dict((k, v if len(v) > 1 else v[0])
            for k, v in urlparse.parse_qs(data).iteritems())
        return qs

    def to_urlencode(self,content):
        pass

Right now, I'm just in local development mode, so all requests are going to localhost:8000, so I haven't enabled any cross-domain posting middleware. I'm able to execute a GET request to the endpoint, /v2/api/clippedcoupon/ just fine, but a POST utterly fails. I'm using POSTMAN in Chrome to test. Can anyone see what I'm doing wrong?

EDIT:

I implemented cookie based authentication for TastyPie and everything is working as expected.


Solution

  • add Following in MIDDLEWARE_CLASSES in your settings.py file

    MIDDLEWARE_CLASSES = ( 'mysite.crossdomainxhr.XsSharing' )

    Copy this file and put it in same level as settings.py

    • crossdomainxhr.py

    from django import http

    try: from django.conf import settings XS_SHARING_ALLOWED_ORIGINS = settings.XS_SHARING_ALLOWED_ORIGINS XS_SHARING_ALLOWED_METHODS = settings.XS_SHARING_ALLOWED_METHODS XS_SHARING_ALLOWED_HEADERS = settings.XS_SHARING_ALLOWED_HEADERS XS_SHARING_ALLOWED_CREDENTIALS = settings.XS_SHARING_ALLOWED_CREDENTIALS except AttributeError: XS_SHARING_ALLOWED_ORIGINS = '*' XS_SHARING_ALLOWED_METHODS = ['POST', 'GET', 'OPTIONS', 'PUT', 'DELETE', 'PATCH'] XS_SHARING_ALLOWED_HEADERS = ['Content-Type', '*'] XS_SHARING_ALLOWED_CREDENTIALS = 'true'

    class XsSharing(object): """ This middleware allows cross-domain XHR using the html5 postMessage API.

    Access-Control-Allow-Origin: http://foo.example
    Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
    
    Based off https://gist.github.com/426829
    """
    def process_request(self, request):
        if 'HTTP_ACCESS_CONTROL_REQUEST_METHOD' in request.META:
            response = http.HttpResponse()
            response['Access-Control-Allow-Origin']  = XS_SHARING_ALLOWED_ORIGINS
            response['Access-Control-Allow-Methods'] = ",".join( XS_SHARING_ALLOWED_METHODS )
            response['Access-Control-Allow-Headers'] = ",".join( XS_SHARING_ALLOWED_HEADERS )
            response['Access-Control-Allow-Credentials'] = XS_SHARING_ALLOWED_CREDENTIALS
            return response
    
        return None
    
    def process_response(self, request, response):
        response['Access-Control-Allow-Origin']  = XS_SHARING_ALLOWED_ORIGINS
        response['Access-Control-Allow-Methods'] = ",".join( XS_SHARING_ALLOWED_METHODS )
        response['Access-Control-Allow-Headers'] = ",".join( XS_SHARING_ALLOWED_HEADERS )
        response['Access-Control-Allow-Credentials'] = XS_SHARING_ALLOWED_CREDENTIALS
    
        return response
    

    this will help