Skip to content Skip to sidebar Skip to footer

Creating A Rest Api For A Django Application

I was given an assignment where I have to create an application API (REST) using the Django technology. I only need to be able to read (GET) the entries from multiple models, join

Solution 1:

Using Tastypie: --

models.py

classUser(Document):
    name =StringField()

api.py

from tastypie import authorization
from tastypie_mongoengine import resources
from project.models import *
from tastypie.resources import *

classUserResource(resources.MongoEngineResource):
classMeta:
    queryset = User.objects.all()
    resource_name = 'user'
    allowed_methods = ('get', 'post', 'put', 'delete','patch')
    authorization = authorization.Authorization()

url.py

from tastypie.apiimportApifrom projectname.apiimport *

v1_api = Api(api_name='v1')
v1_api.register(UserResource())

Javascript (jQuery)

This example is of a GET request:

$(document).ready(function(){
    $.ajax({
       url: 'http://127.0.0.1:8000/api/v1/user/?format=json',
       type: 'GET',                   
       contentType: 'application/json',
       dataType: 'json',
       processData: false,
       success: function(data){
           alert(data)
       //here you will get the data from server
       },
       error: function(jqXHR, textStatus, errorThrown){
              alert("Some Error")                                  
       }
    })
})

For a POST request, change the type to POST and send the data in proper format

For more details, see the Tastypie docs

Solution 2:

I've used Django REST framework, and in general like how it works. The autogenerated human-browsable API screens are quite handy too.

In theory, it doesn't mandate any representation format; you define "serializers" that specify which fields and content to expose, and on which serial format. Still, some formats are easier than others. Ultimately, you can add simple function-based views that return the exact JSON object you want. Even in that case, the framework significantly reduces amount of work needed to get a full API.

Like for Django, the best way is to do the whole tutorial at least once, to get a feeling of what goes where. While doing it, don't yield to the temptation to modify the examples to your specific problems, it only makes things more complicated. After finishing the whole tutorial, you can tell yourself how close the 'easy' formats are to your needs.

Solution 3:

Using Django REST Framework

With Django 1.8.4 and DRF 3.3.3.

Here's a very simple custom JSONSchemaField class you can prop up using Django REST Framework and the jsonschema package (available via pip install jsonschema).

The custom field inherits from DRF's existing JSONField class with some small changes. It add the step of validating incoming JSON against the JSONSchema definition. If the validation passes, the Django model TextField is used to store/retrieve the raw JSON string.

In app/serializers.py

import json
from rest_framework import serializers
from jsonschema import validate  # validates incoming data against JSONSchemafrom jsonschema.exceptions import ValidationError as JSONSchemaValidationError
from .models import Lesson

from .jsonschema import (
    notes_schema,
)


classJSONSchemaField(serializers.JSONField):
# Custom field that validates incoming data against JSONSchema, # Then, if successful, will store it as a string.def__init__(self, schema, *args, **kwargs):
        super(JSONSchemaField, self).__init__(*args, **kwargs)
        self.schema = schema

    defto_representation(self, obj):
        return json.loads(obj)

    defto_internal_value(self, data):
        try:
            validate(data, self.schema)
        except JSONSchemaValidationError as e:
            raise serializers.ValidationError(e.message)

        returnsuper(JSONSchemaField, self).to_internal_value(json.dumps(data))


classLessonSerializer(serializers.HyperlinkedModelSerializer):
    notes = JSONSchemaField(notes_schema)

    classMeta:
        model = Lesson
        fields = ('url', 'title', 'bpm', 'notes')

In app/models.py

from django.db import models


class Lesson(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, blank=True, default='Untitled')
    bpm = models.DecimalField(max_digits=5, decimal_places=2, default=120.00)
    notes = models.TextField()

    class Meta:
        ordering = ('created',)

In app/jsonschema.py

notes_schema = {
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "name": {
                "type": "string",
                "pattern": "^[A-G][#b]?[0-9]$"
            },
            "duration": {
                "type": "string",
                "pattern": "^\d+\/\d+$"
            }
        },
        "required": ["name", "duration"]
    }
}

notes_example = [{"name": "C#4", "duration": "1/4"},
                 {"name": "A4", "duration": "1/32"}]

In app/views.py

from rest_framework import viewsets

from .models import Lesson
from .serializers import LessonSerializer


classLessonViewSet(viewsets.ModelViewSet):
    queryset = Lesson.objects.all()
    serializer_class = LessonSerializer

Solution 4:

Another good combination is Django-Restless, https://django-restless.readthedocs.org/en/latest/, and just building your own serializers within your models. For example

## ModelsclassBlog(models.Model):
    title = models.CharField()
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    text = models.TextField()

    def__init__(self, *args, **kwargs):
        self.super().__init__(*args, **kwargs)
        self.schema = { 
            "title" : self.title,
            "text"  : self.text,
            "user"  : self.user.full_name
        }

    @propertydeflist_view(self):
        fields = ["title","user"]
        return {key: self.schema[key] for key in fields}

    @propertydefdetail_view(self):
        fields = ["title","text","user"]
        return {key: self.schema[key] for key in fields}

## viewsfrom restless.views import Endpoint
from .models import *
classBlogList(Endpoint):
    defget(self, request):
        posts = [blog.list_view for blog in Blog.objects.all()]
        return json.dumps({posts})

and you can add other HTTP verbs as methods as well and use forms for validating this data.

Solution 5:

We use django-piston at the server side to handle REST calls. It has been severing as quite fine.

[Client] ← REST → [Web-Server]—[Django/django-piston]

Also you can see the response in here as well.

Post a Comment for "Creating A Rest Api For A Django Application"