目录
3.3.1 ProductListCreateAPIView 类
3.3.2 ProductRetrieveUpdateDestroyAPIView 类
前言:针对drf框架对比APIView与ViewSet的优缺点与示例,建议先看上一篇【django】Django REST Framework 序列化与反序列化详解-CSDN博客
1、APIView
APIView 类是 DRF 中最基本的类视图。它继承自 Django 的 View 类,并添加了对请求解析、认证、权限检查等的支持。使用 APIView 可以让你更细粒度地控制每个 HTTP 方法的行为。
优点
细粒度控制:你可以完全控制每个 HTTP 方法的行为。
灵活性:适用于需要复杂逻辑的场景。
缺点
冗余代码:对于简单的 CRUD 操作,可能会导致代码重复。
维护成本:随着功能增加,代码量会变得庞大且难以维护。
2、ViewSet
ViewSet 提供了一种更简洁的方式来处理常见的 CRUD 操作。它允许你将多个相关的操作组合在一起,从而减少代码冗余并提高可维护性。
优点
简洁:自动处理常见的 CRUD 操作,减少了代码量。
一致性:提供了一致的 URL 结构和行为。
易于扩展:可以通过覆盖方法轻松扩展功能。
缺点
抽象程度高:对于非常复杂的业务逻辑,可能需要更多的定制。
学习曲线:初学者可能需要时间来理解 ViewSet 的工作原理。
3、APIVIew例子
3.1 模型定义
假设我们有一个简单的库存管理系统,包含以下三张表:Category(类别)、Product(产品)和 Supplier(供应商)。我们将基于这些表来实现类似于之前 Book 表的 CRUD 操作
# newapp/models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(blank=True, null=True)
def __str__(self):
return self.name
class Supplier(models.Model):
name = models.CharField(max_length=100)
contact_person = models.CharField(max_length=100, blank=True, null=True)
email = models.EmailField(blank=True, null=True)
phone = models.CharField(max_length=20, blank=True, null=True)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=255)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock_quantity = models.IntegerField()
description = models.TextField(blank=True, null=True)
def __str__(self):
return self.name
3.2 序列化器定义
# newapp/serializers.py
from rest_framework import serializers
from .models import Category, Product, Supplier
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ['id', 'name', 'description']
class SupplierSerializer(serializers.ModelSerializer):
class Meta:
model = Supplier
fields = ['id', 'name', 'contact_person', 'email', 'phone']
class ProductSerializer(serializers.ModelSerializer):
# 用于写入的字段
category_id = serializers.PrimaryKeyRelatedField(
queryset=Category.objects.all(),
source='category',
write_only=True,
required=True # 确保这个字段是必填的
)
supplier_id = serializers.PrimaryKeyRelatedField(
queryset=Supplier.objects.all(),
source='supplier',
write_only=True,
required=True # 确保这个字段是必填的
)
# 用于读取的嵌套字段
category = CategorySerializer(read_only=True)
supplier = SupplierSerializer(read_only=True)
class Meta:
model = Product
fields = [
'id', 'name', 'category_id', 'category', 'supplier_id', 'supplier',
'price', 'stock_quantity', 'description'
]
def create(self, validated_data):
category = validated_data.pop('category')
supplier = validated_data.pop('supplier')
product = Product.objects.create(
category=category,
supplier=supplier,
**validated_data
)
return product
def update(self, instance, validated_data):
if 'category' in validated_data:
instance.category = validated_data.pop('category')
if 'supplier' in validated_data:
instance.supplier = validated_data.pop('supplier')
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
return instance
def validate(self, data):
if 'category' not in data or 'supplier' not in data:
raise seri