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}
        }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM