rest frame work 教程
来源:互联网 发布:汉化 知乎 编辑:程序博客网 时间:2024/05/14 17:10
1 Serialization
1.1 creating a model
snippets/models.py
from django.db import modelsfrom pygments.lexers import get_all_lexersfrom pygments.styles import get_all_stylesLEXERS = [item for item in get_all_lexers() if item[1]]LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])STYLE_CHOICES = sorted((item, item) for item in get_all_styles())class Snippet(models.Model): created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=100, blank=True, default='') code = models.TextField() linenos = models.BooleanField(default=False) language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100) style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100) class Meta: ordering = ('created',)
1.2 creating a serializer class
serializers.py
from rest_framework import serializersfrom snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICESclass SnippetSerializer(serializers.Serializer): id = serializers.IntegerField(read_only=True) title = serializers.CharField(required=False, allow_blank=True, max_length=100) code = serializers.CharField(style={'base_template': 'textarea.html'}) linenos = serializers.BooleanField(required=False) language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python') style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly') def create(self, validated_data): """ Create and return a new `Snippet` instance, given the validated data. """ return Snippet.objects.create(**validated_data) def update(self, instance, validated_data): """ Update and return an existing `Snippet` instance, given the validated data. """ instance.title = validated_data.get('title', instance.title) instance.code = validated_data.get('code', instance.code) instance.linenos = validated_data.get('linenos', instance.linenos) instance.language = validated_data.get('language', instance.language) instance.style = validated_data.get('style', instance.style) instance.save() return instance
1.3 working with serializer
python manage.py shell
from snippets.models import Snippetfrom snippets.serializers import SnippetSerializerfrom rest_framework.renderers import JSONRendererfrom rest_framework.parsers import JSONParsersnippet = Snippet(code='foo = "bar"\n')snippet.save()snippet = Snippet(code='print "hello, world"\n')snippet.save()
序列化:(data 是 Python native datatypes)serializer = SnippetSerializer(snippet)serializer.data# {'id': 2, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}
content 是json字符串content = JSONRenderer().render(serializer.data)content# '{"id": 2, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}'
Deserialization:(从输入流将数据解析为python native data)from django.utils.six import BytesIOstream = BytesIO(content)data = JSONParser().parse(stream)
实例化为对象,并进行存储serializer = SnippetSerializer(data=data)serializer.is_valid()# Trueserializer.validated_data# OrderedDict([('title', ''), ('code', 'print "hello, world"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])serializer.save()# <Snippet: Snippet object>
序列化query-set(多个对象)serializer = SnippetSerializer(Snippet.objects.all(), many=True)serializer.data# [OrderedDict([('id', 1), ('title', u''), ('code', u'foo = "bar"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', u''), ('code', u'print "hello, world"\n'), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title', u''), ('code', u'print "hello, world"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])]
1.4 using model serializers
修改(重构serializers.py)snippets/serializers.py
class SnippetSerializer(serializers.ModelSerializer): class Meta: model = Snippet fields = ('id', 'title', 'code', 'linenos', 'language', 'style')
检查serializer instance 中的所有字段from snippets.serializers import SnippetSerializerserializer = SnippetSerializer()print(repr(serializer))# SnippetSerializer():# id = IntegerField(label='ID', read_only=True)# title = CharField(allow_blank=True, max_length=100, required=False)# code = CharField(style={'base_template': 'textarea.html'})# linenos = BooleanField(required=False)# language = ChoiceField(choices=[('Clipper', 'FoxPro'), ('Cucumber', 'Gherkin'), ('RobotFramework', 'RobotFramework'), ('abap', 'ABAP'), ('ada', 'Ada')...# style = ChoiceField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful')...
1.5 writing regular django using our serializer
Edit the
snippets/views.py
from django.http import HttpResponse, JsonResponsefrom django.views.decorators.csrf import csrf_exemptfrom rest_framework.renderers import JSONRendererfrom rest_framework.parsers import JSONParserfrom snippets.models import Snippetfrom snippets.serializers import SnippetSerialize
列出所有存在的snippet 和 创建新的snippet()
@csrf_exemptdef snippet_list(request): """ List all code snippets, or create a new snippet. """ if request.method == 'GET': snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return JsonResponse(serializer.data, safe=False) elif request.method == 'POST': data = JSONParser().parse(request) serializer = SnippetSerializer(data=data) if serializer.is_valid(): serializer.save() return JsonResponse(serializer.data, status=201) return JsonResponse(serializer.errors, status=400)
根据pk,对特定snippet做增删改@csrf_exemptdef snippet_detail(request, pk): """ Retrieve, update or delete a code snippet. """ try: snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: return HttpResponse(status=404) if request.method == 'GET': serializer = SnippetSerializer(snippet) return JsonResponse(serializer.data) elif request.method == 'PUT': data = JSONParser().parse(request) serializer = SnippetSerializer(snippet, data=data) if serializer.is_valid(): serializer.save() return JsonResponse(serializer.data) return JsonResponse(serializer.errors, status=400) elif request.method == 'DELETE': snippet.delete() return HttpResponse(status=204)
chuang'jian the snippets/urls.py
from django.conf.urls import urlfrom snippets import viewsurlpatterns = [ url(r'^snippets/$', views.snippet_list), url(r'^snippets/(?P<pk>[0-9]+)/$', views.snippet_detail),]
1.6 teing our web API
测试 API using curl or httpie
pip install httpie
http http://127.0.0.1:8000/snippets/HTTP/1.1 200 OK...[ { "id": 1, "title": "", "code": "foo = \"bar\"\n", "linenos": false, "language": "python", "style": "friendly" }, { "id": 2, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly" }]
http http://127.0.0.1:8000/snippets/2/HTTP/1.1 200 OK...{ "id": 2, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly"}
2 Request and response
2.1 Request object
request.POST # Only handles form data. Only works for 'POST' method.request.data # Handles arbitrary data. Works for 'POST', 'PUT' and 'PATCH' methods.
return Response(data) # Renders to content type as requested by the client.
2.2 Response Object
2.3 Status codes
2.4 Wrapping API views(class based views andfunction based views)
- The
@api_view
decorator for working with function based views. - The
APIView
class for working with class-based views.
2.5 pulling it all together(将以上四点结合使用)
from rest_framework import statusfrom rest_framework.decorators import api_viewfrom rest_framework.response import Responsefrom snippets.models import Snippetfrom snippets.serializers import SnippetSerializer@api_view(['GET', 'POST'])def snippet_list(request): """ List all snippets, or create a new snippet. """ if request.method == 'GET': snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return Response(serializer.data) elif request.method == 'POST': serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@api_view(['GET', 'PUT', 'DELETE'])def snippet_detail(request, pk): """ Retrieve, update or delete a snippet instance. """ try: snippet = Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = SnippetSerializer(snippet) return Response(serializer.data) elif request.method == 'PUT': serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) elif request.method == 'DELETE': snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)
2.6 Adding optional format suffixes to our URLs
1.增加关键参数 format
def snippet_list(request, format=None):
def snippet_list(request, format=None):
2.更新urls.py,,在已经存在的文件上追加 format_suffix_patternsfrom django.conf.urls import urlfrom rest_framework.urlpatterns import format_suffix_patternsfrom snippets import viewsurlpatterns = [ url(r'^snippets/$', views.snippet_list), url(r'^snippets/(?P<pk>[0-9]+)$', views.snippet_detail),]urlpatterns = format_suffix_patterns(urlpatterns)
2.7 How is looking that
http http://127.0.0.1:8000/snippets/HTTP/1.1 200 OK...[ { "id": 1, "title": "", "code": "foo = \"bar\"\n", "linenos": false, "language": "python", "style": "friendly" }, { "id": 2, "title": "", "code": "print \"hello, world\"\n", "linenos": false, "language": "python", "style": "friendly" }]
控制response得到的数据类型 using the Accept
header:http http://127.0.0.1:8000/snippets/ Accept:application/json # Request JSONhttp http://127.0.0.1:8000/snippets/ Accept:text/html # Request HTML
Or by appending a format suffix:http http://127.0.0.1:8000/snippets.json # JSON suffixhttp http://127.0.0.1:8000/snippets.api # Browsable API suffix
控制发送的请求的类型 using the Content-Type
header.# POST using form datahttp --form POST http://127.0.0.1:8000/snippets/ code="print 123"{ "id": 3, "title": "", "code": "print 123", "linenos": false, "language": "python", "style": "friendly"}# POST using JSONhttp --json POST http://127.0.0.1:8000/snippets/ code="print 456"{ "id": 4, "title": "", "code": "print 456", "linenos": false, "language": "python", "style": "friendly"}
3 class based views
3.1 rewriting our API using class based views
对views.py进行重构
from snippets.models import Snippetfrom snippets.serializers import SnippetSerializerfrom django.http import Http404from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import statusclass SnippetList(APIView): """ List all snippets, or create a new snippet. """ def get(self, request, format=None): snippets = Snippet.objects.all() serializer = SnippetSerializer(snippets, many=True) return Response(serializer.data) def post(self, request, format=None): serializer = SnippetSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class SnippetDetail(APIView): """ Retrieve, update or delete a snippet instance. """ def get_object(self, pk): try: return Snippet.objects.get(pk=pk) except Snippet.DoesNotExist: raise Http404 def get(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet) return Response(serializer.data) def put(self, request, pk, format=None): snippet = self.get_object(pk) serializer = SnippetSerializer(snippet, data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def delete(self, request, pk, format=None): snippet = self.get_object(pk) snippet.delete() return Response(status=status.HTTP_204_NO_CONTENT)
refactor url.py
from django.conf.urls import urlfrom rest_framework.urlpatterns import format_suffix_patternsfrom snippets import viewsurlpatterns = [ url(r'^snippets/$', views.SnippetList.as_view()), url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),]urlpatterns = format_suffix_patterns(urlpatterns)
3.2 Using mixins
3.3 using generic class-based views
4 Authentication and permissions
4.1 Adding informations to our models
4.2 Adding endpoints for our user models
4.3 Associating snippet with users
4.4 updating our serializer
4.5 Adding required permission to views
4.6 Adding login to the Browsable API
4.7 Objects level permissions
4.8 Authenticating with the API
5 Relationships and hyperlinked APIS
阅读全文
1 0
- rest frame work 教程
- Django REST frame(官方教程之三)
- ios frame work
- rest-work-eat-study-rest-work-eat or rest-rest-work-work-eat-eat..
- rest教程
- android-application-plug-ins-frame-work
- android-application-plug-ins-frame-work .
- C# Entity frame work的一些操作
- Entity Frame Work 4中的数据库优先
- Entity Frame Work 4代码优先
- android-application-plug-ins-frame-work
- REST教程一:什么是Rest
- SOAP教程 & REST
- Django-Rest-Framework 教程
- rabbitmq 教程 二 Work Queues
- REST教程五:REST服务器响应
- REST教程六:真实的REST示例
- REST教程七:Ajax和REST
- Maven相关
- 常见的数学知识
- JSP页面的九个内置(隐式)对象
- frmentone
- MySQL查询语句
- rest frame work 教程
- MyEclipse html preview 中文乱码解决方法
- selenium无法定位126邮箱
- php时间计算
- 程序员七夕送女友的一个小程序
- 高德地图 信息窗体(InfoWindow)
- Cookbook for R-基础(翻译笔记3)
- 替换字符串中的空格&求字符串最后一个单词的长度
- .net mvc 利用NPOI导入导出excel