from django.core.serializers import serialize class StudentView(APIView): def get(self, request): origin_students = Student.objects.all() serialized_students = serialize("json", origin_students) return HttpResponse(serialized_students)
使用:html
#1. 引入模塊 from rest_framework.views import APIView #2. 繼承APIView class LoginView(APIView): parser_classes = [FormParser] def get(self, request): return render(request, 'parserver/login.html') # .3. 直接request.data就能夠獲取json數據 def post(self, request): # request是被drf封裝的新對象,基於django的request # request.data是一個property,用於對數據進行校驗 # request.data最後會找到self.parser_classes中的解析器 # 來實現對數據進行解析 print(request.data) # {'username': 'alex', 'password': 123} return JsonResponse({"status_code": 200, "code": "OK"})
定義幾個model前端
from django.db import models # Create your models here. class Publish(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField() def __str__(self): return self.name class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() def __str__(self): return self.name class Book(models.Model): title = models.CharField(max_length=32) publishDate = models.DateField() price = models.DecimalField(max_digits=5, decimal_places=2) publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE) authors = models.ManyToManyField(to="Author") def __str__(self): return self.title
GET接口python
url:git
from django.urls import re_path from serializers import views urlpatterns = [ re_path(r'books/$', views.BookView.as_view()) ]
新建一個名爲app_serializers.py的模塊,將全部的序列化的使用集中在這個模塊裏面,對程序進行解耦:django
from rest_framework import serializers from .models import Book
#1.定義序列化類 class BookSeriazlizer(seriazlizers.Serializer):
#2.定義須要返回的字段(字段類型能夠與model中的類型不一致,參數也能夠調整),
字段名稱必須與model中的一致
title = serializers.CharField(max_length=128)
publish_date = serializers.DateTimeField()
price = serializers.DecimalField(max_digits=5, decimal_places=2) publish = serializers.CharField(max_length=32) authors = serializers.CharField(max_length=32)
視圖類,使用序列化組件 json
from rest_framework.views import APIView from rest_framework.response import Response from .models import Book from .app_serializer import BookSerializer class BookView(APIView): def get(self,request):
#3. GET接口邏輯中,獲取QuerySet origin_books = Book.objects.all()
#4.開始序列化 ,many默認爲False,若返回的數據是個多個對象集合,需改成True serialized_books = BookSerializer(origin_books,many=True) return Response(serialized_books.data)
下面是經過POSTMAN請求該接口後的返回的測試數據,除ManyToManyField字段不是想要的外,其餘的都沒有任何問題: app
[ { "title": "Python入門", "publishDate": null, "price": "119.00", "publish": "浙江大學出版社", "authors": "serializers.Author.None" }, { "title": "Python進階", "publishDate": null, "price": "128.00", "publish": "清華大學出版社", "authors": "serializers.Author.None" } ]
若當字段定義爲多個參數時,好比authors.all,取出來的結果將是一個querset,對前端來書,這樣的數據不太友好,稍微改進下post
class BookSerializer(serializers.Serializer): title = serializers.CharField(max_length=32) price = serializers.DecimalField(max_digits=5, decimal_places=2) publishDate = serializers.DateField() publish = serializers.CharField() publish_name = serializers.CharField(max_length=32, read_only=True, source='publish.name') publish_email = serializers.CharField(max_length=32, read_only=True, source='publish.email') # authors = serializers.CharField(max_length=32, source='authors.all') authors_list = serializers.SerializerMethodField() def get_authors_list(self, authors_obj): authors = list() for author in authors_obj.authors.all(): authors.append(author.name) return authors # 注:get_必須與字段名稱一致,不然會報錯
def post(self, request): verified_data = BookSerializer(data=request.data) if verified_data.is_valid(): book = verified_data.save() # 可寫字段經過序列化添加成功以後須要手動添加只讀字段 authors = Author.objects.filter(nid__in=request.data['authors']) book.authors.add(*authors) return Response(verified_data.data) else: return Response(verified_data.errors)
多對多字段一樣須要本身手動來獲取測試
def get_authors_list(self, book_obj): author_list = list() for author in book_obj.authors.all(): author_list.append(author.name) return author_list def create(self, validated_data): # {'title': 'Python666', 'price': Decimal('66.00'), 'publish': '2'} validated_data['publish_id'] = validated_data.pop('publish') book = Book.objects.create(**validated_data) return book def update(self, instance, validated_data): # 更新數據會調用該方法 instance.title = validated_data.get('title', instance.title) instance.publishDate = validated_data.get('publishDate', instance.publishDate) instance.price = validated_data.get('price', instance.price) instance.publish_id = validated_data.get('publish', instance.publish.nid) instance.save() return instance
感受仍是有點麻煩,若字段不少,寫序列化也是一種負擔,更加簡單的方式以下:url
# 繼承ModelSerializer class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ('title', 'price', 'publish', 'authors', 'author_list', 'publish_name', 'publish_city' ) extra_kwargs = { 'publish': {'write_only': True}, 'authors': {'write_only': True} } publish_name = serializers.CharField(max_length=32, read_only=True, source='publish.name') publish_city = serializers.CharField(max_length=32, read_only=True, source='publish.city') author_list = serializers.SerializerMethodField() def get_author_list(self, book_obj): # 拿到queryset開始循環 [{}, {}, {}, {}] authors = list() for author in book_obj.authors.all(): authors.append(author.name) return authors
詳細步驟: