Резюме миксинов django rest framework

задняя часть .NET Django

введение

Эта статья суммирует микс в DRF.
  mixins在drf中主要配合viewset共同使用,实现http方法与mixins的相关类与方法进行关联。 оviewsetВы можете посмотреть мой другой блог, но здесь я не буду слишком много рассказывать.

from rest_framework import viewsets

   В этом наборе представлений, пока существует 5 типов Minxin, они соответствуют http-методам следующим образом:

Mixins
Ниже мы представим Mixins один за другим!

1. CreateModelMixin

# 源码
class CreateModelMixin(object):
    """
    Create a model instance ==>创建一个实例
    """
    def create(self, request, *args, **kwargs):
    
	# 获取相关serializer
        serializer = self.get_serializer(data=request.data)
        
        # 进行serializer的验证
        # raise_exception=True,一旦验证不通过,不再往下执行,直接引发异常
        serializer.is_valid(raise_exception=True)
        
        # 调用perform_create()方法,保存实例
        self.perform_create(serializer)
        
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
    # 保存实例
        serializer.save()

    def get_success_headers(self, data):
        try:
            return {'Location': str(data[api_settings.URL_FIELD_NAME])}
        except (TypeError, KeyError):
            return {}
  Логику этого класса можно увидеть на рисунке выше.Среди них, Perform_create() сохраняет сериализатор напрямую.В некоторых ситуациях нам нужно переписать Perform_create(). Тогда у нас может возникнуть одна из следующих потребностей:

Предположим, что существует модель курса курса, которая поддерживает число для записи количества избранных курсов, а также существует модель userfav для избранного пользователем (должен быть внешний ключ, указывающий на курс), когда пользователь добавляет курс в закладки, по идее теперь пост должен быть экземпляром userfav.Очевидно, нам тоже нужно добавить 1 к числу избранных соответствующего курса.
   В настоящее время нам нужно переписать метод Perform_create()!

def perform_create(self, serializer):
# 重写save的逻辑
	instance = serializer.save()
	course = instance.course
	course.fav_num += 1
	course.save()

   Очевидно, это не единственное решение, мы также можем установить его в сериализаторе, мы также можем использовать семафор drf для его решения!

2. ListModelMixin

# 源码
class ListModelMixin(object):
    """
    List a queryset.==> 列表页获取
    """
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        
        # 这是一个分页功能,如果在viewset中设置了pagination_class,那么这里就会起作用
        # 获取当前页的queryset,如果不存在分页,返回None
        page = self.paginate_queryset(queryset)
        
        if page is not None:
	    # 分页不为空,那么不能简单的执行Response(serializer.data)
	    # 还需要将相关的page信息序列化在进行响应
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

  ListModelMixin обычно используется для получения страницы списка, что в большинстве случаев относительно просто и не требует переписывания связанных методов.

3. RetrieveModelMixin

# 源码
class RetrieveModelMixin(object):
    """
    Retrieve a model instance.==> 获取某一个对象的具体信息
    """
    def retrieve(self, request, *args, **kwargs):
    	# 一般访问的url都为/obj/id/这种新式
    	# get_object()可以获取到这个id的对象
    	# 注意在viewset中设置lookup_field获取重写get_object()方法可以指定id具体对象是什么~!
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

  Вероятность перезаписи метода извлечения относительно высока, например, когда мы увеличиваем количество кликов, нам часто приходится его переписывать.

4. RetrieveModelMixin

# 源码
class UpdateModelMixin(object):
    """
    Update a model instance.==> 更新某个具体对象的内容
    """
    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)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        return Response(serializer.data)

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

    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)

Логика реализации RetrieveModelMixin в основном интегрирует Create и Retrieve. Сначала получите конкретный экземпляр, затем проверьте и сохраните его. Если вам нужно настроить логику обновления, вам нужно переписать метод Perform_update() и попытаться переписать как можно меньше Обновить( )

5. DestroyModelMixin

# 源码
class DestroyModelMixin(object):
    """
    Destroy a model instance.
    """
    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()

Логика   DestroyModelMixin относительно проста.Возьмем пример ниже CreateModelMixin.Когда мы отменяем сбор, в игру вступает наш DestroyModelMixin. так же

def perform_create(self, serializer):
	instance = serializer.save()
	course = instance.course
	if course.fav_num > 0:
		course.fav_num -= 1
	else:
		course.fav_num = 0
	course.save()

резюме

  миксины относительно просты для понимания.Эта статья лишь кратко анализирует содержание исходного кода и логику каждого миксина.Самое главное научиться переписывать связанные с ними методы.
  В обычных условиях, когда мы работаем с определенной моделью, это связано с модификацией данных в другой модели, тогда нам нужно переписать метод выполнения логики сохранения под эти миксины.

CSDN: http://blog.csdn.net/l_vip/article/details/79142105