Skip to content

Instantly share code, notes, and snippets.

@miraculixx miraculixx/cors.py
Last active Jan 12, 2019

Embed
What would you like to do?
To enable CORS support in django-tastypie, use the following code snipet. Then create your tastypie resources as a subclass of BaseCorsResource.Basic code courtesy Daniel Conzalez of http://codeispoetry.me/index.php/make-your-django-tastypie-api-cross-domain/.I added documentation and the post_list method.
'''
Add CORS headers for tastypie APIs
Usage:
class MyModelResource(CORSModelResource):
...
class MyResource(CORSResource):
...
Authors:
original source by http://codeispoetry.me/index.php/make-your-django-tastypie-api-cross-domain/
extensions by @miraculixx
* deal with ?format requests
* always return CORS headers, even if always_return_data is False
* handle exceptions properly (e.g. raise tastypie.BadRequests)
* provide two distinct classes for ModelResource and Resource classes
'''
from django.http.response import HttpResponse
from tastypie import http
from tastypie.exceptions import ImmediateHttpResponse
from tastypie.resources import csrf_exempt
from tastypie.resources import Resource, ModelResource
import logging
class BaseCorsResource(Resource):
"""
Class implementing CORS
"""
def error_response(self, *args, **kwargs):
response = super(BaseCorsResource, self).error_response(*args, **kwargs)
return self.add_cors_headers(response, expose_headers=True)
def add_cors_headers(self, response, expose_headers=False):
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Headers'] = 'content-type, authorization'
if expose_headers:
response['Access-Control-Expose-Headers'] = 'Location'
return response
def create_response(self, *args, **kwargs):
"""
Create the response for a resource. Note this will only
be called on a GET, POST, PUT request if
always_return_data is True
"""
response = super(BaseCorsResource, self).create_response(*args, **kwargs)
return self.add_cors_headers(response)
def post_list(self, request, **kwargs):
"""
In case of POST make sure we return the Access-Control-Allow Origin
regardless of returning data
"""
#logger.debug("post list %s\n%s" % (request, kwargs));
response = super(BaseCorsResource, self).post_list(request, **kwargs)
return self.add_cors_headers(response, True)
def post_detail(self, request, **kwargs):
"""
In case of POST make sure we return the Access-Control-Allow Origin
regardless of returning data
"""
#logger.debug("post detail %s\n%s" (request, **kwargs));
response = super(BaseCorsResource, self).post_list(request, **kwargs)
return self.add_cors_headers(response, True)
def put_list(self, request, **kwargs):
"""
In case of PUT make sure we return the Access-Control-Allow Origin
regardless of returning data
"""
response = super(BaseCorsResource, self).put_list(request, **kwargs)
return self.add_cors_headers(response, True)
def put_detail(self, request, **kwargs):
response = super(BaseCorsResource, self).put_detail(request, **kwargs)
return self.add_cors_headers(response, True)
def method_check(self, request, allowed=None):
"""
Check for an OPTIONS request. If so return the Allow- headers
"""
if allowed is None:
allowed = []
request_method = request.method.lower()
allows = ','.join(map(lambda s: s.upper(), allowed))
if request_method == 'options':
response = HttpResponse(allows)
response['Access-Control-Allow-Origin'] = '*'
response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
response['Access-Control-Allow-Methods'] = "GET, PUT, POST, PATCH"
response['Allow'] = allows
raise ImmediateHttpResponse(response=response)
if not request_method in allowed:
response = http.HttpMethodNotAllowed(allows)
response['Allow'] = allows
raise ImmediateHttpResponse(response=response)
return request_method
def wrap_view(self, view):
@csrf_exempt
def wrapper(request, *args, **kwargs):
request.format = kwargs.pop('format', None)
wrapped_view = super(BaseCorsResource, self).wrap_view(view)
return wrapped_view(request, *args, **kwargs)
return wrapper
#Base Extended Abstract Model
class CORSModelResource(BaseCorsResource, ModelResource):
pass
class CORSResource(BaseCorsResource, Resource):
pass
@doukasd

This comment has been minimized.

Copy link

commented Jun 11, 2014

For me this class was hiding any related resources from being returned when accessing a resource. I solved this by changing the base class of BaseCorsResource from Resource to ModelResource.

@miraculixx

This comment has been minimized.

Copy link
Owner Author

commented Sep 11, 2014

Thanks for your feedback. It should work when using CORSModelResource instead of BaseCorsResource.

@marcelometal

This comment has been minimized.

Copy link

commented Jan 9, 2016

django-cors-headers is a good alternative

@singhprabhanshu

This comment has been minimized.

Copy link

commented Jan 10, 2017

please tell me the way i can implement the code. Is that code is written in api.py for tastypie like
from tastypie.authorization import Authorization
from tastypie import fields
from django.db import models
from tastypie.resources import ModelResource, ALL, ALL_WITH_RELATIONS
from .models import Guest
from jakhar.api import urlencodeSerializer, AdminApiKeyAuthentication, UserResource
from tastypie.authorization import DjangoAuthorization, ReadOnlyAuthorization

from django.http.response import HttpResponse
from tastypie import http
from tastypie.exceptions import ImmediateHttpResponse
from tastypie.resources import csrf_exempt
from tastypie.resources import Resource, ModelResource
import logging

class GuestResource(ModelResource):
user = fields.ForeignKey(UserResource, 'user')
class Meta:
queryset = Guest.objects.all()
resource_name = 'guest'
allowed_methods = ['get', 'post', 'delete', 'put', 'patch']
filtering = {
'guest_fname': ALL,
'user': ALL_WITH_RELATIONS,
'guest_timestamp': ALL

    }

	limit = 0
	always_return_data = True
	authentication = AdminApiKeyAuthentication()
	authorization = Authorization()
	serializer = urlencodeSerializer()

class BaseCorsResource(ModelResource):
"""
Class implementing CORS
"""
def error_response(self, *args, **kwargs):
response = super(BaseCorsResource, self).error_response(*args, **kwargs)
return self.add_cors_headers(response, expose_headers=True)

def add_cors_headers(self, response, expose_headers=False):
    response['Access-Control-Allow-Origin'] = '*'
    response['Access-Control-Allow-Headers'] = 'content-type, authorization'
    if expose_headers:
        response['Access-Control-Expose-Headers'] = 'Location'
    return response    

def create_response(self, *args, **kwargs):
    """
    Create the response for a resource. Note this will only
    be called on a GET, POST, PUT request if 
    always_return_data is True
    """
    response = super(BaseCorsResource, self).create_response(*args, **kwargs)
    return self.add_cors_headers(response)

def post_list(self, request, **kwargs):
    """
    In case of POST make sure we return the Access-Control-Allow Origin
    regardless of returning data
    """
    #logger.debug("post list %s\n%s" % (request, kwargs));
    response = super(BaseCorsResource, self).post_list(request, **kwargs)
    return self.add_cors_headers(response, True)

def post_detail(self, request, **kwargs):
    """
    In case of POST make sure we return the Access-Control-Allow Origin
    regardless of returning data
    """
    #logger.debug("post detail %s\n%s" (request, **kwargs));
    response = super(BaseCorsResource, self).post_list(request, **kwargs)
    return self.add_cors_headers(response, True)

def put_list(self, request, **kwargs):
    """
    In case of PUT make sure we return the Access-Control-Allow Origin
    regardless of returning data
    """
    response = super(BaseCorsResource, self).put_list(request, **kwargs)
    return self.add_cors_headers(response, True)    

def put_detail(self, request, **kwargs):
    response = super(BaseCorsResource, self).put_detail(request, **kwargs)
    return self.add_cors_headers(response, True)
    
def method_check(self, request, allowed=None):
    """
    Check for an OPTIONS request. If so return the Allow- headers
    """
    if allowed is None:
        allowed = []
        
    request_method = request.method.lower()
    allows = ','.join(map(lambda s: s.upper(), allowed))

    if request_method == 'options':
        response = HttpResponse(allows)
        response['Access-Control-Allow-Origin'] = '*'
        response['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
        response['Access-Control-Allow-Methods'] = "GET, PUT, POST, PATCH"
        response['Allow'] = allows
        raise ImmediateHttpResponse(response=response)

    if not request_method in allowed:
        response = http.HttpMethodNotAllowed(allows)
        response['Allow'] = allows
        raise ImmediateHttpResponse(response=response)

    return request_method

def wrap_view(self, view):
    @csrf_exempt
    def wrapper(request, *args, **kwargs):
        request.format = kwargs.pop('format', None)
        wrapped_view = super(BaseCorsResource, self).wrap_view(view)
        return wrapped_view(request, *args, **kwargs)
    return wrapper

#Base Extended Abstract Model
class CORSModelResource(BaseCorsResource, ModelResource):
pass

class CORSResource(BaseCorsResource, Resource):
pass

@singhprabhanshu

This comment has been minimized.

Copy link

commented Jan 11, 2017

For the CORS:
pip install django-cors-headers
Go to django settings.py and then follow the given steps:
INSTALLED_APPS = (
...
'corsheaders',
...
)
MIDDLEWARE = [ # Or MIDDLEWARE_CLASSES on Django < 1.10
...
'corsheaders.middleware.CorsMiddleware',

...

]

CORS_ORIGIN_ALLOW_ALL = True

Thats done for CROS!!!!#

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.