drf之视图组件

文章详细介绍了DjangoRestFramework中基于GenericAPIView的不同视图基类实现,如BookView和BookDetailView,以及ModelViewSet的使用,展示了如何通过继承和组合Mixins来处理CRUD操作和序列化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.两个视图基类

1.1继承GenericAPIView+序列化类+Response写接口

class BookView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request):
        object_list = self.get_queryset()
        ser = self.get_serializer(instance=object_list, many=True)
        return Response(ser.data)

    def post(self, request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)
        return Response(ser.errors)


class BookDetailView(GenericAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request, *args, **kwargs):
        obj = self.get_object()
        ser = self.get_serializer(instance=obj)
        return Response(ser.data)

    def put(self, request, *args, **kwargs):
        obj = self.get_object()
        ser = self.get_serializer(instance=obj, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)
        return Response(ser.errors)

    def delete(self, request, *args, **kwargs):
        self.get_object().delete()
        return Response('')

1.2继承GenericAPIView和五个视图扩展类

class BookView(GenericAPIView, CreateModelMixin, ListModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request):
        return super().list(request)

    def post(self, request):
        return super().create(request)


class BookDetailView(GenericAPIView, RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get(self, request, *args, **kwargs):
        return super().retrieve(request)

    def put(self,request, *args, **kwargs):
        return super().update(request)

    def delete(self,request, *args, **kwargs):
        return super().destroy(request)

1.3继承九个视图子类

class BookView(ListCreateAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

class BookDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

1.4视图集

class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    
# 路由
    path('books/', BookView.as_view({'get': 'list', 'post': 'create'})),
    path('books/<int:pk>', BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    
#映射 
get:  list------->查所有
post: create----->增数据

get: retrieve---->查单条
put: update------>改数据
delete: destroy-->删数据

1.5序列化类

from rest_framework import serializers
from .models import Book, Publish, Author, AuthorDetail


class BookSerializer(serializers.ModelSerializer):
    publish_detail = serializers.DictField(read_only=True)
    author_list = serializers.ListField(read_only=True)

    class Meta:
        model = Book
        fields = ['name', 'price', 'publish', 'authors', 'publish_detail', 'author_list']
        extra_kwargs = {
            'publish': {'write_only': True},
            'authors': {'write_only': True},
            'publish_detail': {'read_only': True},
            'author_list': {'read_only': True},
        }

1.6表模型

from django.db import models


class Book(models.Model):
    name = models.CharField(max_length=64)
    price = models.IntegerField()

    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')

    def publish_detail(self):
        return {'name': self.publish.name, 'addr': self.publish.addr}

    def author_list(self):
        l = []
        for author in self.authors.all():
            l.append({'name': author.name, 'age': author.age, 'phone': author.authordetail.phone,
                      'addr': author.authordetail.addr})
        return l


class Publish(models.Model):
    name = models.CharField(max_length=64)
    addr = models.CharField(max_length=128)


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()

    authordetail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)


class AuthorDetail(models.Model):
    phone = models.IntegerField()
    addr = models.CharField(max_length=64)

2.两个视图基类

# APIView

# GenericAPIView
queryset = None # 用于获取模型实例的查询集
serializer_class = None  # 用于序列化和反序列化模型实例的序列化器类
lookup_field = 'pk'   # 用于查找单个模型实例的字段
lookup_url_kwarg = None  # URL中用于查找模型实例的关键字参数的名称

def get_queryset(self):
	# 断言 queryset不是空 
    assert self.queryset is not None, (
        "'%s' should either include a `queryset` attribute, "
        "or override the `get_queryset()` method."
        % self.__class__.__name__
    )
    # 将视图类的queryset赋值给queryset后续使用赋值后的变量
    queryset = self.queryset
    # 判断queryst是不是QuerySet对象
    if isinstance(queryset, QuerySet对象):
        # 查询数据 防止遗漏数据
        queryset = queryset.all()
    return queryset

def get_object(self):
    queryset = self.filter_queryset(self.get_queryset())

    lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field

    assert lookup_url_kwarg in self.kwargs, (
        'Expected view %s to be called with a URL keyword argument '
        'named "%s". Fix your URL conf, or set the `.lookup_field` '
        'attribute on the view correctly.' %
        (self.__class__.__name__, lookup_url_kwarg)
    )

    obj = get_object_or_404(queryset, **filter_kwargs) # 对象不存在就404

    return obj # 返回对象

def get_serializer(self, *args, **kwargs):
    # 获取序列化类
    serializer_class = self.get_serializer_class()
    kwargs.setdefault('context', self.get_serializer_context())
    return serializer_class(*args, **kwargs)

def get_serializer_class(self):
    assert self.serializer_class is not None, (
        "'%s' should either include a `serializer_class` attribute, "
        "or override the `get_serializer_class()` method."
        % self.__class__.__name__
    )

    return self.serializer_class 	# 不为空直接返回

3.五个视图扩展类

# CreateModelMixin	增
def create(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    self.perform_create(serializer) # 可以重写 增加扩展性
    return Response(serializer.data)

def perform_create(self, serializer):
	serializer.save()

# ListModelMixin	查所有
def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())
    serializer = self.get_serializer(queryset, many=True)
    return Response(serializer.data)
    
# RetrieveModelMixin	查单条
def retrieve(self, request, *args, **kwargs):
    instance = self.get_object()
    serializer = self.get_serializer(instance)
    return Response(serializer.data)
# UpdateModelMixin	修改
def update(self, request, *args, **kwargs):
    partial = kwargs.pop('partial', False)
    instance = self.get_object()
    serializer = self.get_serializer(instance, data=request.data, partial=partial)
    serializer.is_valid(raise_exception=True)
    self.perform_update(serializer) # 可以重写 增加扩展性
    return Response(serializer.data)

def perform_update(self, serializer):
    serializer.save()
# DestroyModelMixin	删除
def destroy(self, request, *args, **kwargs):
    instance = self.get_object()
    self.perform_destroy(instance)
    return Response(status=status.HTTP_204_NO_CONTENT)

def perform_destroy(self, instance):
    instance.delete()

4.九个视图子类

# ListCreateAPIView(ListModelMixin,CreateModelMixin,GenericAPIView)  查所有,新增(get,post)
def get(self, request, *args, **kwargs):
    return self.list(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
    return self.create(request, *args, **kwargs)

# RetrieveUpadateDestroyAPIView(RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView) 查单条,修改,删除(get,put,delete)
def get(self, request, *args, **kwargs):
    return self.retrieve(request, *args, **kwargs)

def put(self, request, *args, **kwargs):
    return self.update(request, *args, **kwargs)

def delete(self, request, *args, **kwargs):
	return self.destroy(request, *args, **kwargs)
# RetrieveUpdateAPIView(RetrieveModelMixin,UpdateModelMixin,GenericAPIView) 查单条,修改(get,put)
def get(self, request, *args, **kwargs):
    return self.retrieve(request, *args, **kwargs)

def put(self, request, *args, **kwargs):
    return self.update(request, *args, **kwargs)

# RetrieveDestroyAPIView(RetrieveModelMixin,DestroyModelMixin,GenericAPIView) 查单条,删除(get,delete)
def get(self, request, *args, **kwargs):
    return self.retrieve(request, *args, **kwargs)

def delete(self, request, *args, **kwargs):
    return self.destroy(request, *args, **kwargs)

# CreateAPIView(CreateModelMixin,GenericAPIView)	增加(post)
def post(self, request, *args, **kwargs):
    return self.create(request, *args, **kwargs)

# ListAPIView(ListModelMixin,GenericAPIView)	查所有(get)
def get(self, request, *args, **kwargs):
    return self.list(request, *args, **kwargs)

# RetrieveAPIView(RetrieveModelMixin,GenericAPIView)	查单条(get)
def get(self, request, *args, **kwargs):
    return self.retrieve(request, *args, **kwargs)

# UpdateAPIView(UpdateModelMixin,GenericAPIView)	修改(put)
def put(self, request, *args, **kwargs):
    return self.update(request, *args, **kwargs)

# DestroyAPIView(DestroyModelMixin,GenericAPIView)	删除(delete)
def delete(self, request, *args, **kwargs):
    return self.destroy(request, *args, **kwargs)

5.视图集

# ModelViewSet(CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,ListModelMixin,GenericViewSet):
path('books/', views.BookView.as_view({'get':'list(查所有)','post':'create(增加数据)'})),
path('books/<int:pk>', views.BookView.as_view({'get':'retrieve(查单条)','put':'update(修改)','delete':'destroy(删除)'})),
# 分别对应以下五个方法:
def create(self, request, *args, **kwargs):
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid(raise_exception=True)
    self.perform_create(serializer) # 可以重写 增加扩展性
    return Response(serializer.data)

def list(self, request, *args, **kwargs):
    queryset = self.filter_queryset(self.get_queryset())
    serializer = self.get_serializer(queryset, many=True)
    return Response(serializer.data)

def retrieve(self, request, *args, **kwargs):
    instance = self.get_object()
    serializer = self.get_serializer(instance)
    return Response(serializer.data)

def update(self, request, *args, **kwargs):
    partial = kwargs.pop('partial', False)
    instance = self.get_object()
    serializer = self.get_serializer(instance, data=request.data, partial=partial)
    serializer.is_valid(raise_exception=True)
    self.perform_update(serializer) # 可以重写 增加扩展性
    return Response(serializer.data)

def destroy(self, request, *args, **kwargs):
    instance = self.get_object()
    self.perform_destroy(instance)
    return Response(status=status.HTTP_204_NO_CONTENT)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值