Git Product home page Git Product logo

django-ajaxutils's Introduction

AJAX requests for Ponies™

How many times you found yourself writing some views in Django to handle an AJAX request? And how many times you just copy-pasted a view written for synchronous requests and edited them to return a JSON object? And so, how many times you forgot that that @login_required will actually redirect the request to the login page in case of anonymous users? If this happened to you as many times as it happened to us, you may be start considering using django-ajaxutils.

Django-ajaxutils allows you to define a view as an AJAX view that will return a JSON object and that will handle correctly errors such as user not authenticated and invalid requests. Everything through a simple decorator!

image

Installation

Just go for:

pip install django-ajaxutils

to do the magic.

Usage

If you want to define a view for handling an AJAX request, you have just to decorate it with @ajax and return a dictionary representing the object to be returned as JSON. If you lack of imagination, check this out:

from ajaxutils.decorators import ajax


@ajax()
def check_for_some_task(request):
    exit_status = get_status_of_some_task()
    if exit_status is None:
        return {
            'status': 'pending'
        }

    return {
        'status': 'completed',
        'exit_status': exit_status
    }

Requiring authentication

If your view requires the user to be authenticated, just write it:

@ajax(login_required=True)
def some_very_private_view(request):
    data = perform_something_private()
    return {
        'data': data
    }

In case of an unauthenticated request, a 401: Unauthorized response containing the following JSON object will be returned:

{
    'status': 'error',
    'error': 'Unauthorized',
}

Requiring GET / POST

@ajax also allows you a quick way to require a particular method for requesting the view. For example, if your view will edit some server-side data, you may accept only POST requests. With @ajax this is as easy as remembering the first two decimal digits of PI (which are 1 and 4, btw):

@ajax(login_required=True, require_POST=True)
def submit_my_data(request):
    new_obj = save_my_data()
    return {
        'id': new_obj.pk
    }

This will return a 405: Method not allowed response with the following JSON object in case of illegal requests:

{
    'status': 'error',
    'error': 'Method not allowed',
}

You can of course set require_GET=True for GET requests.

You can also use this alternative syntax:

@ajax(methods=["GET", "POST"])
def my_cool_view(request):
    return {
        'hello': 'world!'
    }

Custom Status Codes

What if you don't want to return an HTTP 200? Do you want to return a 404? Write:

from django.http import Http404

@ajax()
def my_cool_view(request):
    raise Http404

This returns:

{
    'status': 'error',
    'error': 'Not found',
}

Or maybe a 400 - Bad Request:

from django.http import HttpResponseBadRequest

@ajax()
def my_cool_view(request):
    return HttpResponseBadRequest('My error message')

This returns:

{
    'status': 'error',
    'error': 'My error message',
}

and the HTTP response has status code 400.

Another syntax, more Flask-ish:

@ajax()
def my_cool_view(request):
    return {
        "i'm a": 'teapot'
    }, 418

From infinity import json

Tired of writing infinite import statements to choose the best json module? Let ajaxutils do it for you:

from ajaxutils import json

At the moment, ajaxutils prefers simplejson over the stdlib json. No other json module is used. In the future we will probably provide support to ujson using a Django setting.

Changelog

v0.2

  • Moved JsonResponse to ajaxutils.http
  • Added Custom Status Codes handling
  • Added documentation for @ajax(require=METHOD)
  • Added "from ajaxutils import json"

django-ajaxutils's People

Contributors

nostalgiaz avatar vad avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

django-ajaxutils's Issues

basic authentication

support fo basic authentication via decorator

Implementation proposal:

import base64

from django.http import HttpResponse
from django.contrib.auth import authenticate, login


def basicauth_required(realm=""):
    "Based on http://djangosnippets.org/snippets/243/"

    def external_wrapper(view):
        def wrapper(request, *args, **kwargs):
            if 'HTTP_AUTHORIZATION' in request.META:
                auth = request.META['HTTP_AUTHORIZATION'].split()               
                if len(auth) == 2:
                    if auth[0].lower() == "basic":
                        uname, passwd = base64.b64decode(auth[1]).split(':')
                        user = authenticate(username=uname, password=passwd)
                        if user is not None:
                            if user.is_active:
                                login(request, user)
                                request.user = user
                                return view(request, *args, **kwargs)

            # the authorization attempt failed. Send a 401
            # back to them to ask them to authenticate.
            #
            response = HttpResponse()
            response.status_code = 401
            response['WWW-Authenticate'] = 'Basic realm="%s"' % realm
            return response
        return wrapper
    return external_wrapper

Error 403 on POST

When I try a POST request I'll end up with a 403 FORBIDDEN error.

  @ajax(require_POST=True)

is set.

Can't specify error codes

I'd like to be able to specify the status code of the response, something like:

try:
  something_nasty()
except:
  return {
    'some-info': 'here', 
    'some-other': here',
  }, 418 

require a list of methods

It would be helpful to have something like

@ajax(require=('get', 'post'))
def my_view(request):
    pass

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.