1. 程式人生 > >Rest framework——從一段json資料來學rest_framework

Rest framework——從一段json資料來學rest_framework

一、用 Django 來返回一段 json 資料列表

import json
from .models import Product
from django.http import HttpResponse
from django.views.generic.base import View

class ProductListView1(View):
	def get(self, request):
			"""
			通過 django 的 view 實現
			"""
			json_list = []
			products = Product.objects.all()
	
			# 某些資料型別無法直接序列化 繁瑣
for product in products: json_dict = {} json_dict["id"] = product.id json_dict["name"] = product.name json_dict["category"] = product.category json_list.append(json_dict) return HttpResponse(json.dumps(json_list), content_type="application/json") # 某些資料型別無法直接序列化
from django.forms.models import model_to_dict for product in products: json_dict = model_to_dict(product) json_list.append(json_dict) return HttpResponse(json.dumps(json_list), content_type="application/json") # 使用django自帶序列化類 from django.core import serializers json_data =
serializers.serialize('json', product) return HttpResponse(json_data, content_type="application/json") # 使用 JsonResponse from django.http import JsonResponse json_data = json.loads(serializers.serialize('json', product)) return JsonResponse(json_data, safe=False)

二、使用rest_framwork來返回json資料

# serializers.py
from rest_framework import serializers
from .models import Product

# s1 自定義欄位序列化
class ProductSerializer(serializers.Serializer):
	id = serializers.IntegerField()
	name = serializers.CharField(required=True, max_length=100)

	# 重寫create函式可以儲存前端傳的資料
	def create(self, validated_data):
		return Product.objects.create(**validated_data)
		
# s2 根據model來序列化欄位(指定或全部)
# 或存在自定義欄位 自定義欄位將替換指定欄位中的該欄位
class ProductSerializer(serializers.ModelSerializer):
	class Meta:
		model = Product
		fields = ('id', 'name')
		# 序列化全部欄位
		# fields = ("__all__")
		
# s3 序列化外來鍵欄位
# 若序列化類中存在外來鍵欄位,外來鍵欄位將自動序列化為外來鍵id
class CategorySerializer(serializers.Serializer):
	id = serializers.IntegerField()
	name = serializers.CharField(required=True, max_length=100)


class ProductSerializer(serializers.ModelSerializer):
	# 將外來鍵欄位資訊按 CategorySerializer 類序列化
	category = CategorySerializer()
	# 將外來鍵欄位序列化顯示為外來鍵中的某一欄位
	#category = serializers.CharField('category.name')
	class Meta:
		model = Product
		fields = ('id', 'name')
		# 序列化全部欄位
		# fields = ("__all__")
		
	
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from .serializers import ProductSerializer
from .models import Product

# v1-s1:s2:s2
class ProductList(APIView):
	def get(self,request,format=None):
		products = Product.objects.all()
		products_serializer = ProductSerializer(goods, many=True)
		return Response(products_serializer.data)
		
	def post(self,request,format=None):
		serializer = ProductSerializer(data=request.data)
		# 對前端提交的資料進行驗證
		if serializer.is_valid():
			serializer.save()
			return Response(serializer.data, status=status.HTTP_201_CREATED)
		return Respnse(serializer.errors, status=status.HTTP_400)

# v2
from rest_framework import mixins
from rest_framework import generics

class ProductList(mixins.ListModelMixin, generics.GenericAPIView):
	products = Product.objects.all()
	serializer_class = ProductSerializer
	
	def get(self, request, *args, **kwgras):
		return self.list(request, *args, **kwargs)
	
		
# v3
class ProductList(generics.ListAPIView):
	products = Product.objects.all()
	serializer_class = ProductSerializer


# v4-url viewset
from rest_framework import viewsets
class ProductList(mixins.ListModelMixin, viewsets.GenericViewSet):
	products = Product.objects.all()
	serializer_class = ProductSerializer	

#urls.py
from .views import ProductList
# u1
products = ProductList.as_view({
	'get': 'list',
	'post': 'create'
})
url (r'product/$', product, name='product')


#u2
from rest_framework.routers import DefaultRouter
# 這樣寫的好處是不用重複性的註冊大量相似的url
router = DefaultRouter()
router.register(r'product', ProductList)
url(r'^', include(router.urls))
# 繼承關係
GenericViewSet(viewset)			--rest_framework
	GenericAPIView				--rest_framework
		APIView					--rest_framework
			View				--django