Django REST framework 序列化与请求响应
安装 pip install djangorestframework
以出版社和书籍为例,启动一个Django项目
django-admin startproject mysite
cd mysite
python manage.py startapp public
python manage.py startapp book
1. INSTALLED_APPS注册rest_framework
INSTALLED_APPS = [
...
'rest_framework',
]
2. 创建model
-
book/models.py
class Book(models.Model): name = models.CharField(max_length=128, verbose_name='书名') price = models.FloatField("价格", default=0) public = models.ForeignKey(Public, on_delete=models.CASCADE, verbose_name="出版社") create_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) class Meta: db_table = 'Book' verbose_name = '书名' verbose_name_plural = verbose_name def __str__(self): return f"{self.name}"
-
public/models.py
class Public(models.Model): name = models.CharField(max_length=128, verbose_name="出版社") address = models.CharField(max_length="256", verbose_name="地址") create_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) class Meta: db_table = 'Public' verbose_name = '出版社' verbose_name_plural = verbose_name def __str__(self): return f"{self.name}"
3. 创建serializers.py
-
public/serializers.py
class PublicSnippetSerializer(serializers.ModelSerializer): class Meta: model = Public fields = ('id', 'name', 'address')
-
book/serializers.py
from rest_framework import serializers from book.models import Book from public.serializers import PublicSerializer # 用于展示get请求的序列化 class BookSerializer(serializers.ModelSerializer): public = PublicSerializer() class Meta: model = Book fields = ('id', 'name', 'price', "public") # 用于 post put请求的修改序列化 class PostBookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ('id', 'name', 'price', "public")
由于有时获取数据和修改创建数据需要的序列化格式不同,所以可以创建不同的序列化类
4. views
-
public/views
from django.shortcuts import render from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from public.models import Public from public.serializers import PublicSnippetSerializer @api_view(['GET', 'POST']) def public_view(request): """ 列出所有的public,或者创建一个新的public。 """ if request.method == 'GET': publics = Public.objects.all() serializer = PublicSnippetSerializer(publics, many=True) return Response(serializer.data) elif request.method == 'POST': serializer = PublicSnippetSerializer(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 public_detail_view(request, id): """ 获取,更新或删除一个public实例。 """ try: public = Public.objects.get(id=id) except Public.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = PublicSnippetSerializer(public) return Response(serializer.data) elif request.method == 'PUT': serializer = PublicSnippetSerializer(public, 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': public.delete() return Response(status=status.HTTP_204_NO_CONTENT)
-
public/views
from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from book.models import Book from book.serializers import BookSerializer, PostBookSerializer @api_view(['GET', 'POST']) def book_list_view(request): if request.method == 'GET': books = Book.objects.all() serializer = BookSerializer(books, many=True) return Response(serializer.data) elif request.method == 'POST': # 使用PostBookSerializer serializer = PostBookSerializer(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 book_detail_view(request, id): """ 获取,更新或删除一个book实例。 """ try: book = Book.objects.get(id=id) except Book.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) if request.method == 'GET': serializer = BookSerializer(book) return Response(serializer.data) elif request.method == 'PUT': # 使用PostBookSerializer serializer = PostBookSerializer(book, 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': book.delete() return Response(status=status.HTTP_204_NO_CONTENT)
5. 配置路由
-
主路由
from django.conf.urls import url from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), url(r'^v1/api/public/', include('public.urls')), ]
-
public/urls.py
from django.conf.urls import url from public import views urlpatterns = [ url(r'^public/$', views.public_view), url(r'^public/(?P<id>[0-9]+)/$', views.public_detail_view), ]
-
book/urls.py
from django.conf.urls import url from book import views urlpatterns = [ url(r'^book/$', views.book_list_view), url(r'^book/(?P<id>[0-9]+)/$', views.book_detail_view), ]
6. 访问
pubilc
-
所有列表
-
获取 get http://127.0.0.1:8000/v1/api/public/public/
-
新建 post
请求体body中加入
{ "name":"长春大学出版社", "address":"长春" }
这里模式和表单提交相似form-data, 也可以用json
-
指定id数据
-
获取 get http://127.0.0.1:8000/v1/api/public/public/2/
-
修改 put http://127.0.0.1:8000/v1/api/public/public/2/
请求体body中加入
name:吉林大学出版社 address:吉林
这里模式和表单提交相似form-data, 也可以用json
-
删除 delete http://127.0.0.1:8000/v1/api/public/public/2/
-
book
-
所有列表
-
获取 get http://127.0.0.1:8000/v1/api/book/book/
[ { "id": 1, "name": "三国演义", "price": 38.5, "public": { "id": 1, "name": "北京大学出版社", "address": "北京" } }, { "id": 2, "name": "水浒传", "price": 25.0, "public": { "id": 1, "name": "北京大学出版社", "address": "北京" } }, ]
-
新建 post http://127.0.0.1:8000/v1/api/book/book/
请求体body中加入
{ "name": "红楼梦", "price": 25.0, "public": 1 # public_id }
-
-
指定id数据
-
获取 get http://127.0.0.1:8000/v1/api/book/book/2/
-
修改 put http://127.0.0.1:8000/v1/api/book/book/2/
请求体body中加入
{ "name": "红楼梦", "price": 25.0, "public": 2 }
这里模式和表单提交相似form-data, 也可以用json
-
删除 delete http://127.0.0.1:8000/v1/api/book/book/2/
-