我获得了一项任务,我必须使用Django技术创建应用程序API(REST)。我只需要能够从多个模型中读取(GET)条目,加入它们,并使用JSON格式(一个或多个对象)返回它们。 json架构和适当的json文件示例已经提供给我了。
由于这是我第一次创建API而且我不熟悉Django,所以我很乐意向您提供一些指导。
我搜索了两个似乎最受欢迎的框架:
正如我所见,这两个版本使您可以快速为您的应用程序设置API。但是我可以使用其中一种创建自定义JSON格式,还是有其他方法可以做到这一点?
答案 0 :(得分:18)
<强> 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
答案 1 :(得分:12)
我使用过Django REST框架,总的来说它是如何工作的。自动生成的人类可浏览的API屏幕也非常方便。
理论上,它没有强制要求任何表示格式;定义“序列化程序”,指定要公开的字段和内容,以及使用哪种串行格式。有些格式比其他格式更容易。最终,您可以添加简单的基于函数的视图,返回所需的确切JSON对象。即使在这种情况下,该框架也显着减少了获得完整API所需的工作量。
对于Django来说,最好的方法是至少完成一次整个教程,以了解其中的内容。在这样做时,不要屈服于将示例修改为特定问题的诱惑,它只会使事情变得更复杂。完成整个教程后,您可以告诉自己“简单”格式与您的需求有多接近。
答案 2 :(得分:5)
使用Django REST Framework
使用Django 1.8.4
和DRF 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
答案 3 :(得分: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谓词作为方法,并使用表单来验证此数据。
答案 4 :(得分:0)
我们在服务器端使用django-piston来处理REST调用。 它已经切断了很好。
[客户]←REST→[Web服务器] - [Django / django-piston]
您还可以在here as well.
中看到回复