DRF 简单使用(详细注释版)

1.djangorestframework使用

  1. 下载安装
pip install djangorestframework  ## djangorestframework
pip install django-filter  ## 过滤使用
  1. 注册
INSTALLED_APPS = [
    ...
    'rest_framework',
    'django_filters'
]
  1. model
class Feedback(models.Model):
    type_choice = (
        (0, '未分类'),
        (1, '学习笔记'),
        (2, '学员评价'),
        (3, '入职邀约'),
    )

    img = models.ImageField(upload_to='img/feedback/')
    back_type = models.IntegerField(choices=type_choice, default=0)
  1. 路由
url(r'^ajax_feedback/', views.AjaxFeedback.as_view()),
  1. 视图
from rest_framework import generics
from web.serializers import FeedbackSerializer
from web.pagination import DefaultPagination
from django_filters.rest_framework import DjangoFilterBackend


class AjaxFeedback(generics.ListAPIView):
    queryset = models.Feedback.objects.all()
    serializer_class = FeedbackSerializer
    pagination_class = DefaultPagination
    filter_backends = [DjangoFilterBackend, ]
    filter_fields = ['back_type']
  1. 序列化器类
from rest_framework import serializers
from repository import models


class FeedbackSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Feedback
        fields = ['img']
  1. 分页类
from rest_framework.pagination import PageNumberPagination

class DefaultPagination(PageNumberPagination):
    page_size = 8  # 一页多少条数据
    page_query_param = 'page'  # 分页查询条件的key
    page_size_query_param = 'size'
    # max_page_size = 8

2.序列化器serializer

序列化: 将对象,字符串等数据类型转化为可用于传输/存储的数据形式

  • -----serializer文件-----
from rest_framework import serializers
from app01 import models

# 获取外键名称
class PublisherSerializer(serializers.Serializer):
    name = serializers.CharField()

# 1.自定义序列化器获取manytomany外键名称
class AuthorSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField()


class BookSerializer(serializers.Serializer):
    # 要序列化的书籍参数
    title = serializers.CharField()
    price = serializers.DecimalField(max_digits=6, decimal_places=2)
    pub_date = serializers.DateTimeField()
    # 仅仅在get需要的字段
    pub = PublisherSerializer(required=False, read_only=True) # 获取外键字段名称,自定义序列化器
    authors = serializers.SerializerMethodField(read_only=True)  # 获取多对多字段名称 1.自定义序列化器 2.自定义 get_字段名字段名
    
    # 仅仅在post需要的字段
    post_pub = serializers.IntegerField(write_only=True)
    post_author = serializers.ListField(write_only=True)
    
     # 2.自定义 get_字段名
    def get_authors(self, obj): # obj是书籍对象
        ser_obj = AuthorSerializer(obj.authors.all(), many=True)
        return ser_obj.data
    
    
    # 新建数据写入数据库时自定义create方法
    def create(self, validated_data):# validated_data校验过的数据
        # 写入数据
        book_obj = models.Book.objects.create(
            title=validated_data['title'],
            price=validated_data['price'],
            pub_date=validated_data['pub_date'],
            pub_id=validated_data['post_pub']
        )
        book_obj.authors.set(validated_data['post_author'])
        return book_obj
    
    
    # put方法执行到save方法是,执行update
    def update(self, instance, validated_data):
        instance.title = validated_data.get('title',instance.title)# 使用get请求方法防止在部分修改数据时报错
        instance.price = validated_data.get('price',instance.price)
        instance.pub_date = validated_data.get('pub_date',instance.pub_date)
        instance.pub_id = validated_data.get('post_pub',instance.pub_id)
        instance.save()
        instance.authors.set(validated_data.get('post_authors',instance.authors.all()))
        return instance
  • -----view文件-----
from app_rest import models

from rest_framework.views import APIView
from rest_framework.response import Response  # rest_framework返回对象
from app_rest.serializer import BookSerializer


class BookList(APIView):
    """查询新增"""

    # 获取数据
    def get(self, request, *args, **kwargs):
        all_books = models.Book.objects.all()
        ser_data = BookSerializer(all_books, many=True)  # many=True可以加入一个对象列表,单个对象不需要加入many参数
        return Response(ser_data.data)

    # 提交数据
    def post(self, request, *args, **kwargs):
        ser_obj = BookSerializer(data=request.data)
        if ser_obj.is_valid():
            ser_obj.save()
            return Response(ser_obj.data)
        return Response(ser_obj.errors)


class BookView(APIView):
    """修改删除"""

    def get(self, request, pk, *args, **kwargs):
        """查询到要修改的数据"""
        book_obj = models.Book.objects.filter(pk=pk).first()
        ser_obj = BookSerializer(instance=book_obj)
        return Response(ser_obj.data)

    def put(self, request, pk, *args, **kwargs):
        """
        提交要修改的数据
        :return:
        """
        book_obj = models.Book.objects.filter(pk=pk).first()
        ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True)  # partial=True 允许部分修改
        if ser_obj.is_valid():
            ser_obj.save()
            return Response(ser_obj.data)
        return Response(ser_obj.errors)

    def delete(self, request, pk, *args, **kwargs):
        """删除"""
        obj = models.Book.objects.filter(pk=pk).first()
        if obj:
            obj.delete()
            return Response({'msg': '删除成功'})
        return Response({'error': '数据不存在'})
  • ---data.json---需要数据结构

    {
      "title": "桃花侠大战菊花怪1",
      "price": "111.11",
      "pub_date": "2019-01-01T10:10:10Z",
      "post_pub": 1,
      "post_author": [
        1,
        2
      ]
    }

3. 序列化器钩子

  • 自定义校验器

    from rest_framework import serializers
    
    def validate_title(value):
        if '苍老师' in value:
            raise serializers.ValidationError
        return value
    
    class BookSerializer(serializers.Serializer):
        # 要序列化的书籍参数
        title = serializers.CharField(validators=[])
  • 局部钩子与全局钩子

    class BookSerializer(serializers.Serializer):
        title = serializers.CharField()
        price = serializers.DecimalField(max_digits=6, decimal_places=2)
        pub_date = serializers.DateTimeField()
      # 仅仅在get需要的字段
        pub = PublisherSerializer(required=False, read_only=True) # 获取外键字段名称,自定义序列化器
        authors = serializers.SerializerMethodField(read_only=True)  # 获取多对多字段名称 1.自定义序列化器 2.自定义 get_字段名字段名
    
      # 仅仅在post需要的字段
        post_pub = serializers.IntegerField(write_only=True)
        post_author = serializers.ListField(write_only=True)
    
         # 2.自定义 get_字段名
        def get_authors(self, obj): # obj是书籍对象
            ser_obj = AuthorSerializer(obj.authors.all(), many=True)
            return ser_obj.data
    
    
        # 局部钩子
        def validate_title(self,value):
            if '苍老师' in value:
                raise serializers.ValidationError
            return value
    
        # 全局钩子
        def validate(self,attrs):
            if '苍老师' in attrs:
                raise serializers.ValidationError
          return attrs
    

4.modelserializer

from rest_framework import serializers

# 获取外键名称
class PublisherSerializer(serializers.Serializer):
    name = serializers.CharField()

# 1.自定义序列化器获取manytomany外键名称
class AuthorSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField()



# 显示字段
class BookSerializer(serializers.modelSerializer):
    
    # 显示外键以及多对多字段的name
    pub_info = serializers.SerializerMethodField(read_only = True )
    authors_info = serializers.SerializerMethodField(read_only = True )
    
    def get_pub_info(self,obj):
        return PublisherSerializer(obj,pub).data
    
    def get_authors_info(self,obj):
        return AuthorSerializer(obj,author.all(),many = True).data
    
    
    class Meta:
        model = models.Book
        fields = '__all__'
        
        #给字段加限制
        extra_kwargs = {
            'pub':{'write_only':True},
            'authors':{'write_only':True}
        }

你可能感兴趣的:(DRF 简单使用(详细注释版))