Python 为 Django 应用程序创建 REST API
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17577177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating a REST API for a Django application
提问by TheAptKid
I was given an assignment where I have to create an application API (REST) using the Django technology. I only need to be able to read (GET) the entries from multiple models, join them, and return them using the JSON format (one or more objects). The json schema and an example of an appropriate json file were already given to me.
我接到了一个任务,我必须使用 Django 技术创建一个应用程序 API (REST)。我只需要能够读取 (GET) 来自多个模型的条目,加入它们,并使用 JSON 格式(一个或多个对象)返回它们。json 模式和一个合适的 json 文件的例子已经给了我。
Since this is my first time creating an API and I'm not very familliar with Django, I would kindly ask you for some guidance.
由于这是我第一次创建 API 并且我对 Django 不是很熟悉,我想请您提供一些指导。
I googled up two frameworks which seem to be the most popular:
我在谷歌上搜索了两个似乎最受欢迎的框架:
As I've seen these two enable you to quickly setup your API for your application. But can I create a custom JSON format using one of them or is there another way of doing this?
正如我所看到的,这两个使您能够为您的应用程序快速设置 API。但是我可以使用其中的一个创建自定义 JSON 格式,还是有其他方法可以做到这一点?
回答by Javier
I've used Django REST framework, and in general like how it works. The autogenerated human-browsable API screens are quite handy too.
我使用过 Django REST 框架,并且一般喜欢它的工作方式。自动生成的人类可浏览的 API 屏幕也非常方便。
In theory, it doesn't mandate any representation format; you define "serializers" that specify which fields and content to expose, and on which serial format. Still, some formats are easier than others. Ultimately, you can add simple function-based views that return the exact JSON object you want. Even in that case, the framework significantly reduces amount of work needed to get a full API.
理论上,它不强制要求任何表示格式;您定义“序列化程序”,指定要公开哪些字段和内容,以及使用哪种串行格式。不过,某些格式比其他格式更容易。最终,您可以添加简单的基于函数的视图,返回您想要的确切 JSON 对象。即使在这种情况下,该框架也显着减少了获得完整 API 所需的工作量。
Like for Django, the best way is to do the whole tutorial at least once, to get a feeling of what goes where. While doing it, don't yield to the temptation to modify the examples to your specific problems, it only makes things more complicated. After finishing the whole tutorial, you can tell yourself how close the 'easy' formats are to your needs.
就像 Django 一样,最好的方法是至少做一次整个教程,以了解什么会发生在哪里。这样做时,不要屈服于针对您的特定问题修改示例的诱惑,它只会使事情变得更加复杂。完成整个教程后,您可以告诉自己“简单”格式与您的需求有多接近。
回答by Ming Chan
We use django-pistonat the server side to handle REST calls. It has been severing as quite fine.
我们在服务器端使用django-piston来处理 REST 调用。它一直很好地切断。
[Client] ← REST → [Web-Server]—[Django/django-piston]
[客户端] ← REST → [Web-Server]—[Django/ django-piston]
Also you can see the response in here as well.
回答by Nullify
Using Tastypie: --
使用 Tastypie:-
models.py
模型.py
class User(Document):
name = StringField()
api.py
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
网址.py
from tastypie.api import Api
from projectname.api import *
v1_api = Api(api_name='v1')
v1_api.register(UserResource())
Javascript (jQuery)
Javascript (jQuery)
This example is of a GET request:
这个例子是一个 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")
}
})
})
For a POST request, change the type to POST
and send the data
in proper format
对于 POST 请求,将类型更改为POST
并data
以正确的格式发送
For more details, see the Tastypie docs
有关更多详细信息,请参阅Tastypie 文档
回答by user1876508
Another good combination is Django-Restless, https://django-restless.readthedocs.org/en/latest/, and just building your own serializers within your models. For example
另一个很好的组合是 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})
and you can add other HTTP verbs as methods as well and use forms for validating this data.
并且您也可以添加其他 HTTP 动词作为方法并使用表单来验证此数据。
回答by jfunk
Using Django REST Framework
使用 Django REST 框架
With Django 1.8.4
and DRF 3.3.3
.
随着Django 1.8.4
和DRF 3.3.3
。
Here's a very simple custom JSONSchemaField class you can prop up using Django REST Framework and the jsonschema
package (available via pip install jsonschema
).
这是一个非常简单的自定义 JSONSchemaField 类,您可以使用 Django REST 框架和jsonschema
包(通过 提供pip install jsonschema
)来支持。
The custom field inherits from DRF's existing JSONField
class with some small changes. It add the step of validating incoming JSON against the JSONSchema definition. If the validation passes, the Django model TextField
is used to store/retrieve the raw JSON string.
自定义字段继承自 DRF 的现有JSONField
类,并进行了一些小的更改。它添加了根据 JSONSchema 定义验证传入 JSON 的步骤。如果验证通过,TextField
则使用Django 模型来存储/检索原始 JSON 字符串。
In app/serializers.py
在 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')
In app/models.py
在 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',)
In app/jsonschema.py
在 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"}]
In app/views.py
在 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