Подтвердить что ты не робот

Создание REST API для приложения Django

Мне было предоставлено задание, где я должен создать API-интерфейс приложения (REST) ​​с использованием технологии Django. Мне нужно только читать (GET) записи из нескольких моделей, присоединяться к ним и возвращать их с использованием формата JSON (один или несколько объектов). Схема json и пример соответствующего json файла уже были предоставлены мне.

Поскольку это мой первый раз, когда я создаю API, и я не очень люблю Django, я прошу вас дать некоторое руководство.

Я искал две рамки, которые кажутся самыми популярными:

Как я видел, эти два варианта позволяют быстро настроить API для вашего приложения. Но могу ли я создать собственный формат JSON, используя один из них, или есть ли другой способ сделать это?

4b9b3361

Ответ 1

Использование 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)

Этот пример представляет собой запрос 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")                                  
       }
    })
})

Для запроса POST измените тип на POST и отправьте data в надлежащем формате

Подробнее см. Документы Tastypie

Ответ 2

Я использовал структуру Django REST и вообще как это работает. Автогенерируемые экраны API, доступные для просмотра человеком, также весьма удобны.

Теоретически, он не предусматривает какого-либо формата представления; вы определяете "сериализаторы", которые определяют, какие поля и контент должны быть выставлены, и на каком последовательном формате. Тем не менее, некоторые форматы проще других. В конечном счете, вы можете добавить простые функциональные представления, которые возвращают точный объект JSON, который вы хотите. Даже в этом случае структура значительно сокращает объем работы, необходимой для получения полного API.

Как и для Django, лучший способ - по крайней мере один раз сделать весь учебник, чтобы понять, что происходит. Выполняя это, не поддавайтесь соблазну изменить примеры к вашим конкретным проблемам, это только усложняет ситуацию. После завершения всего учебника вы можете сказать, насколько близки "легкие" форматы к вашим потребностям.

Ответ 3

Еще одна хорошая комбинация - Django-Restless, https://django-restless.readthedocs.org/en/latest/ и просто построение собственных сериализаторов в ваших моделях. Например

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

и вы можете добавить другие HTTP-глаголы как методы, а также использовать формы для проверки этих данных.

Ответ 4

Использование Django REST Framework

С Django 1.8.4 и DRF 3.3.3.

Здесь очень простой пользовательский класс JSONSchemaField, который вы можете использовать с помощью Django REST Framework и пакета jsonschema (доступный через pip install jsonschema).

Пользовательское поле наследует существующий класс JSONField существующего DRF с небольшими изменениями. Он добавляет шаг проверки входящего JSON на определение JSONSchema. Если проверка прошла, модель Django TextField используется для хранения/извлечения исходной строки JSON.

В приложении /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')

В приложении /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',)

В приложении /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"}]

В приложении /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

Ответ 5

Мы используем django-piston на стороне сервера для обработки вызовов REST. Это было очень хорошо.

[Клиент] ← REST → [Веб-сервер] - [Django/django-piston]

Также вы можете увидеть ответ в здесь.