Creando una API REST para una aplicación Django

Me asignaron una tarea en la que tengo que crear una aplicación API (REST) ​​utilizando la tecnología Django. Solo necesito poder leer (GET) las entradas de varios modelos, unirlas y devolverlas utilizando el formato JSON (uno o más objetos). El esquema json y un ejemplo de un archivo json apropiado ya me fueron entregados.

Como esta es la primera vez que creo una API y no estoy muy familiarizado con Django, le pido ayuda.

Busqué en Google dos marcos que parecen ser los más populares:

  • Tastypie
  • Django REST framework

Como he visto, estos dos le permiten configurar rápidamente su API para su aplicación. Pero, ¿puedo crear un formato JSON personalizado utilizando uno de ellos o hay otra forma de hacerlo?

Utilizando Tastypie: –

modelos.py

class User(Document): name = StringField() 

api.py

 from tastypie import authorization from tastypie_mongoengine import resources from project.models import * from tastypie.resources import * class UserResource(resources.MongoEngineResource): class Meta: queryset = User.objects.all() resource_name = 'user' allowed_methods = ('get', 'post', 'put', 'delete','patch') authorization = authorization.Authorization() 

url.py

 from tastypie.api import Api from projectname.api import * v1_api = Api(api_name='v1') v1_api.register(UserResource()) 

Javascript (jQuery)

Este ejemplo es de una solicitud GET:

 $(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") } }) }) 

Para una solicitud POST, cambie el tipo a POST y envíe los data en el formato adecuado

Para más detalles, ver la documentación de Tastypie.

He utilizado el framework Django REST, y en general me gusta cómo funciona. Las pantallas API autogeneradas por humanos son también muy útiles.

En teoría, no exige ningún formato de representación; define “serializadores” que especifican qué campos y contenido exponer, y en qué formato de serie. Aún así, algunos formatos son más fáciles que otros. En última instancia, puede agregar vistas simples basadas en funciones que devuelven el objeto JSON exacto que desea. Incluso en ese caso, el marco reduce significativamente la cantidad de trabajo necesario para obtener una API completa.

Al igual que para Django, la mejor manera es hacer todo el tutorial al menos una vez, para tener una idea de lo que va a dónde. Mientras lo hace, no ceda a la tentación de modificar los ejemplos para sus problemas específicos, solo hace las cosas más complicadas. Después de terminar todo el tutorial, puedes decirte cuán cerca están los formatos “fáciles” de tus necesidades.

Usando el framework REST de Django

Con Django 1.8.4 y DRF 3.3.3 .

Aquí hay una clase JSONSchemaField personalizada muy simple que puede apuntalar utilizando el Marco REST de Django y el paquete jsonschema (disponible a través de pip install jsonschema ).

El campo personalizado se hereda de la clase JSONField existente de JSONField con algunos pequeños cambios. Agrega el paso de validar el JSON entrante contra la definición de JSONSchema. Si la validación pasa, el modelo TextField Django se utiliza para almacenar / recuperar la cadena JSON sin formato.

En app / serializers.py

 import json from rest_framework import serializers from jsonschema import validate # validates incoming data against JSONSchema from jsonschema.exceptions import ValidationError as JSONSchemaValidationError from .models import Lesson from .jsonschema import ( notes_schema, ) class JSONSchemaField(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 def to_representation(self, obj): return json.loads(obj) def to_internal_value(self, data): try: validate(data, self.schema) except JSONSchemaValidationError as e: raise serializers.ValidationError(e.message) return super(JSONSchemaField, self).to_internal_value(json.dumps(data)) class LessonSerializer(serializers.HyperlinkedModelSerializer): notes = JSONSchemaField(notes_schema) class Meta: model = Lesson fields = ('url', 'title', 'bpm', 'notes') 

En 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',) 

En la aplicación / jsonschema.py

 notes_schema = { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string", "pattern": "^[AG][#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"}] 

En la aplicación / views.py

 from rest_framework import viewsets from .models import Lesson from .serializers import LessonSerializer class LessonViewSet(viewsets.ModelViewSet): queryset = Lesson.objects.all() serializer_class = LessonSerializer 

Otra buena combinación es Django-Restless, https://django-restless.readthedocs.org/en/latest/ , y solo está creando sus propios serializadores dentro de sus modelos. Por ejemplo

 ## Models class Blog(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 } @property def list_view(self): fields = ["title","user"] return {key: self.schema[key] for key in fields} @property def detail_view(self): fields = ["title","text","user"] return {key: self.schema[key] for key in fields} ## views from restless.views import Endpoint from .models import * class BlogList(Endpoint): def get(self, request): posts = [blog.list_view for blog in Blog.objects.all()] return json.dumps({posts}) 

y puede agregar otros verbos HTTP como métodos y usar formularios para validar estos datos.

Usamos django-piston en el lado del servidor para manejar las llamadas REST. Ha estado cortando como bastante bien.

[Cliente] ← RESTO → [Servidor web] – [Django / django-piston ]

También puedes ver la respuesta aquí también.