【问题标题】:Creating a REST API for a Django application为 Django 应用程序创建 REST API
【发布时间】:2013-07-08 18:26:51
【问题描述】:

我被分配了一项任务,我必须使用 Django 技术创建一个应用程序 API (REST)。我只需要能够从多个模型中读取 (GET) 条目,加入它们,然后使用 JSON 格式(一个或多个对象)返回它们。 json 架构和相应 json 文件的示例已经提供给我。

由于这是我第一次创建 API,而且我对 Django 不是很熟悉,所以我想请您提供一些指导。

我搜索了两个似乎最受欢迎的框架:

正如我所见,这两个使您能够为您的应用程序快速设置 API。但是我可以使用其中一个创建自定义 JSON 格式,还是有其他方法可以做到这一点?

【问题讨论】:

  • 我不确定@user1876508 的上述评论是否仍然准确。 DRF 确实支持嵌套序列化,并且已经使用了很长时间。

标签: python django rest


【解决方案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 docs

【讨论】:

    【解决方案2】:

    我使用过 Django REST 框架,总的来说喜欢它的工作原理。自动生成的可供人工浏览的 API 屏幕也非常方便。

    理论上,它不强制要求任何表示格式;您定义“序列化程序”,指定要公开哪些字段和内容,以及使用哪种串行格式。不过,有些格式比其他格式更容易。最终,您可以添加简单的基于函数的视图,这些视图返回您想要的确切 JSON 对象。即使在这种情况下,该框架也显着减少了获得完整 API 所需的工作量。

    与 Django 一样,最好的方法是至少完成整个教程一次,以了解具体内容。这样做时,不要屈服于根据您的具体问题修改示例的诱惑,这只会使事情变得更加复杂。完成整个教程后,您可以告诉自己“简单”格式与您的需求有多接近。

    【讨论】:

      【解决方案3】:

      使用 Django REST 框架

      使用Django 1.8.4DRF 3.3.3

      这是一个非常简单的自定义 JSONSchemaField 类,您可以使用 Django REST Framework 和 jsonschema 包(可通过 pip install jsonschema 获得)来支持。

      自定义字段继承自 DRF 的现有 JSONField 类,并进行了一些小改动。它添加了根据 JSONSchema 定义验证传入 JSON 的步骤。如果验证通过,Django 模型TextField 用于存储/检索原始 JSON 字符串。

      在 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')
      

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

      在 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"}]
      

      在 app/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】:

        另一个很好的组合是 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 动词作为方法,并使用表单来验证此数据。

        【讨论】:

          【解决方案5】:

          我们在服务器端使用django-piston 来处理 REST 调用。 它一直很好。

          [客户端] ← REST → [Web-服务器]—[Django/django-piston]

          你也可以在here as well.看到回复

          【讨论】:

          • 我强烈建议不要在新项目中使用 django-piston。它已经很久没有维护了。 sweetpie 和 django rest 框架功能更全面,维护积极,大型社区可以为您提供帮助。
          猜你喜欢
          • 1970-01-01
          • 2014-10-19
          • 2020-02-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-15
          相关资源
          最近更新 更多