GithubHelp home page GithubHelp logo

django-generic-json-views's Introduction

Django Generic JSON Views

Stories in Ready Build Status PyPi version

Class based generic views that render JSON data.

The django.views.generic package has several generic class based views that render HTML for a model or a set of applications and provide an API to use those views and modify querysets and context data. However, Django recommends that to specify the output of JSON data, you use a mixin or another approach to render_to_response the JSON.

Many AJAX applications, however, have the need for quick views like the ones specified the in the generic package to either serialize a model or to provide other context data in the View logic. These generic views allow that, and correctly render JSON data with the correct HTTP Headers.

More documentation can be found at Read the Docs: Django Generic JSON Views Documentation

Installation

The easiest way to install this library is to use pip as follows:

$ pip install django-generic-json-views

Alternatively you can download the source code and run the following:

$ python setup.py install

You can import from the json_views.views module.

Otherwise copy the views.py file to a utils directory in your Django Project and import it correctly from there.

Basic Usage

There are several provided classes that work right off the bat:

  • JSONDataView
  • JSONDetailView
  • JSONListView
  • PaginatedJSONListView
  • JSONFormView

These classes all provide the following functionality:

  1. Render the output of get_context_data as a JSON object
  2. Serialize Django Models and Querysets with a Lazy Encoder
  3. Correctly add the application/json HTTP header
  4. Remove duplicate objects and middleware context built into Django

The most simple example is the JSONDataView which will allow you to output generic JSON data as needed:

from datetime import datetime
from json_views.views import JSONDataView


class JSONTime(JSONDataView):

    def get_context_data(self, **kwargs):
        context = super(JSONTime, self).get_context_data(**kwargs)
        context['current_time'] = datetime.now().strftime("%c")
        return context

In order to render the detail view of a model as a JSON serialization, use the JSONDetailView -- note that this view can be used for both serialization and deserialization as noted in the section below.

from json_views.views import JSONDetailView


class CustomerJSON(JSONDetailView):

    model = Customer

Many JSON views are centered around lists, hence the JSONListView and the PaginatedJSONListView.

from json_views.views import JSONListView


class ProductsJSON(JSONListView):

    model = Product

The PaginatedJSONListView looks up the special parameter page=n to decide which part of the list to return. It also removes the Django paginator object and returns the following data:

{
    'pages': Number,
    'count': Number,
    'is_paginated': Bool,
    'per_page': Number,
    'current': Number,
    'object_list': List
}

An example of using this view is:

from json_views.views import PaginatedJSONListView


class PaginatedProducts(PaginatedJSONListView):

    paginate_by = 10
    count_query = 'count'
    count_only  = False

    def get_querset(self):
        return Product.objects.filter(instores=True)

count_query specifies the name of the property to pass in as kwargs in a GET request that will force the view to only return the total number of expected items, and not fetch them from the db. E.g. if you use /?count=true in your url, the view will respond only with the total number.

Finally the JSONFormView accepts incoming JSON data to populate a form rather than waiting for HTTP POST data, this is how you would do AJAX login forms. Note that GET requests are not allowed.

from json_views.views import JSONFormView


class LoginForm(JSONFormView):

    form = LoginForm

In the form view, a parameter success is passed back, as either True or False. This can be customized by overriding get_context_data.

Serialization & Deserialization

The lazy encoder attempts to serialze the model into a dictionary or other compatible JSON-Python type, and does so in a recursive fashion, continuing to serialize objects, the default serialization is this:

  1. If the object is an iterable- construct a list
  2. If the object extends ModelBase attempt to call a serialize method
  3. Utilize force_unicode to force the object to unicode data.

Therefore if your Models provide a serialize method that returns a dictionary, you can very easily control what fields and what format the model is serialized to.

Additionally you can specify a @classmethod deserialize that accepts as input a dictionary and returns an instance of the Model.

Here is an example of the serialization of a UserProfile, as an extension of the django.contrib.auth package.

class UserProfile(models.Model):

    user  = models.OneToOneField( 'django.contrib.auth.User', editable=False, related_name='profile' )
    bio   = models.CharField( max_length=255, null=True, blank=True, default=None )
    birth = models.DateField( )

    def serialize(self):
        return {
            'username': self.user.username,
            'email': self.user.email,
            'name': " ".join((self.user.first_name, self.user.last_name)),
            'birthday': self.birth.strftime("%d %M, %Y"),
        }

    @classmethod
    def deserialize(klass, data):
        username = data.get('username', None)
        if username:
            try:
                return klass.objects.get(username=username)
            except klass.DoesNotExist:
                pass
        return klass(**data)

Pushing to PyPi

A couple of notes on pushing this software to PyPi:

  1. Version Bump
    1. Change the version in __init__.py
    2. Change the version in tests
    3. Change the download URL in setup.py
  2. Tag the release git tag -a v0.x.x
  3. Push to Github
  4. Register python setup.py register -r pypi
  5. Upload python setup.py sdist upload -r pypi

Contributors

Thanks to @philippbosch for helping provide Python 3 support with later versions of Django.

Thanks to @freeworlder who provided Django 1.10 compatibility.

django-generic-json-views's People

Contributors

bbengfort avatar freeworlder avatar philippbosch avatar tofumatt avatar waffle-iron 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

django-generic-json-views's Issues

Push library to PyPi

Here are the steps that need to be done to get this Library ready to go on PyPi:

  • make the module a "generic django app" in order to test
  • add test library for Django 1.5-1.8
  • setup continuous integration with Travis
  • add a Makefile for test and push to PyPi
  • add a setup.cfg
  • update documentation as required

Profit!

Refactor

Break out the JSON handling libraries into its own file, make the views separate, etc.

Django 2.0 Support

Under Django 2.0, getting errors like:

'DatabaseOperations' object has no attribute 'select'

Seems to be some kind of problem with GeoDjango.

Add testing for Django 1.5-1.7

For some reason the testing is breaking for 1.5 and 1.6 so we are only testing 1.7.

This is related to the DJANGO_SETTINGS_MODULE configuration somehow, see the conftest.py module for more on how it is working for Django 1.7 - just not earlier versions.

Finish the tests

There are several "pending implementation" skipped tests, as well as a whole suite of untested stuff in the tests library; this needs to be updated.

Specific Django version in requirements.txt

Hi, first of all thanks for this package.

When I run pip install django-generic-json-views it will install specific Django version (it is pinned in https://github.com/bbengfort/django-generic-json-views/blob/master/requirements.txt#L2). But this will break my existing venv, I have to keep Django 1.6.x branch.

In my opinion it is good practice to have min and max versions of required packages, e.g. https://github.com/pennersr/django-allauth/blob/master/setup.py#L124.

UTF-8 encoding of response

Hello there and thanks for a nice library!

There is a little mishap: if encoded JSON happens to contain UTF-8, it become garbled with some clients. This is because ideally Content-Type should contain charset=utf-8, too.

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.