web-dev-qa-db-fra.com

Créer un REST API pour une application Django

On m'a confié une tâche dans laquelle je dois créer une API d'application (REST) ​​à l'aide de la technologie Django. Je dois seulement pouvoir lire (GET) les entrées de plusieurs modèles, les joindre et les renvoyer au format JSON (un ou plusieurs objets). Le schéma json et un exemple de fichier json approprié m'ont déjà été donnés.

Etant donné que c’est la première fois que je crée une API et que je ne connais pas très bien Django, je vous prie de bien vouloir vous guider.

J'ai googlé deux cadres qui semblent être les plus populaires:

Comme je l'ai déjà vu, ces deux outils vous permettent de configurer rapidement votre API pour votre application. Mais puis-je créer un format JSON personnalisé en utilisant l’un d’eux ou existe-t-il un autre moyen de procéder?

28
TheAptKid

Utilisation de Tastypie: -

models.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)

Cet exemple est une requête 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")                                  
       }
    })
})

Pour une demande POST, changez le type en POST et envoyez le data au format approprié.

Pour plus de détails, voir Docs Tastypie

18
Nullify

J'ai utilisé le framework Django REST, et en général, j'apprécie son fonctionnement. Les écrans d'API auto-générés à navigation humaine sont également très pratiques.

En théorie, il n’exige aucun format de représentation; vous définissez des "sérialiseurs" qui spécifient les champs et le contenu à exposer et sur quel format de série. Certains formats sont quand même plus faciles que d’autres. En fin de compte, vous pouvez ajouter des vues simples basées sur des fonctions qui renvoient exactement l'objet JSON souhaité. Même dans ce cas, le cadre réduit considérablement le travail nécessaire pour obtenir une API complète.

Comme pour Django, le meilleur moyen est de faire tout le tutoriel au moins une fois, pour avoir une idée de ce qui se passe où. Ce faisant, ne cédez pas à la tentation de modifier les exemples en fonction de vos problèmes spécifiques, cela ne fera que compliquer les choses. Après avoir terminé l'ensemble du didacticiel, vous pouvez vous dire à quel point les formats «faciles» répondent à vos besoins.

12
Javier

Utilisation de Django REST Framework

Avec Django 1.8.4 et DRF 3.3.3.

Voici une classe JSONSchemaField personnalisée très simple que vous pouvez configurer avec Django REST Framework et le package jsonschema (disponible via pip install jsonschema). 

Le champ personnalisé hérite de la classe JSONField existante de DRF avec quelques modifications mineures. Il ajoute l'étape de validation du JSON entrant par rapport à la définition de JSONSchema. Si la validation réussit, le modèle Django TextField est utilisé pour stocker/récupérer la chaîne JSON brute.

Dans l'application/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')

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

Dans l'application/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"}]

Dans l'application/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
4
jfunk

Django-Restless, https://Django-restless.readthedocs.org/en/latest/ est une autre bonne combinaison. Il vous suffit de créer vos propres sérialiseurs dans vos modèles. Par exemple

## 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})

et vous pouvez également ajouter d'autres verbes HTTP comme méthodes et utiliser des formulaires pour valider ces données.

4
user1876508

Nous utilisons Django-piston côté serveur pour traiter les appels REST . 

[Client] ← REST → [Serveur Web] - [Django / Django-piston ]

Vous pouvez aussi voir la réponse dans ici aussi.

0
Ming Chan