【django】Django REST Framework 构建 API:APIView 与 ViewSet

目录

1、APIView

2、ViewSet

3、APIVIew例子

3.1 模型定义

3.2 序列化器定义

3.3 使用视图

3.3.1 ProductListCreateAPIView 类

3.3.2 ProductRetrieveUpdateDestroyAPIView 类

3.4 配置url

3.5 测试

3.5.1 查询全部

3.5.2 添加产品

3.5.3 查询单个产品 

3.5.4 修改单个产品

3.5.5 删除单个产品

4、VIEWSet例子

4.1 模型定义

4.2 序列化器定义

4.3 使用视图

4.4 配置url

4.5 测试

4.5.1 查询全部

4.5.2 添加产品

 4.5.3 查询单个产品

4.5.4 修改单个产品

4.5.5 删除单个产品

5、总结

5.1  APIView

5.2 ViewSet


前言:针对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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春天的菠菜

一毛两毛也是动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值