Django 之restfromwork 序列化組件實現數據增刪查改


rest-framework序列化之Serializer

models.py

from django.db import models

# Create your models here.


class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.IntegerField()
    pub_date=models.DateField()
    publish=models.ForeignKey("Publish")
    authors=models.ManyToManyField("Author")
    def __str__(self):
        return self.title

class Publish(models.Model):
    name=models.CharField(max_length=32)
    email=models.EmailField()
    def __str__(self):
        return self.name

class Author(models.Model):
    name=models.CharField(max_length=32)
    age=models.IntegerField()
    def __str__(self):
        return self.name

view部分:

from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
from django.shortcuts import HttpResponse
from django.core import serializers  # django 自帶的序列化組件


from rest_framework import serializers

class BookSerializers(serializers.Serializer):
    title=serializers.CharField(max_length=32)
    price=serializers.IntegerField()
    pub_date=serializers.DateField()
    publish=serializers.CharField(source="publish.name")
    #authors=serializers.CharField(source="authors.all")
    authors=serializers.SerializerMethodField()
    def get_authors(self,obj):
        temp=[]
        for author in obj.authors.all():
            temp.append(author.name)
        return temp
  #此處可以繼續用author的Serializers,
  # def get_authors(self,obj):
    #     ret=obj.authors.all()
    #     ss=AuthorSerializer(ret,many=True)
    #     return ss.data

class BookViewSet(APIView):

    def get(self,request,*args,**kwargs):
        book_list=Book.objects.all()
        # 序列化方式1:
        # from django.forms.models import model_to_dict
        # import json
        # data=[]
        # for obj in book_list:
        #     data.append(model_to_dict(obj))
        # print(data)
        # return HttpResponse("ok")

        # 序列化方式2:
        # data=serializers.serialize("json",book_list)
        # return HttpResponse(data)

        # 序列化方式3:
        bs=BookSerializers(book_list,many=True)     #many=True代表有多條數據,如果只有一條數據,many=False
        return Response(bs.data)
     # 序列化方式4: 
      # ret=models.Book.objects.all().values('nid','title')
     # dd=list(ret)
        # return HttpResponse(json.dumps(dd))


注意:

​ source 如果是字段,會顯示字段,如果是方法,會執行方法,不用加括號(authors=serializers.CharField(source='authors.all'))

​ 如在模型中定義一個方法,直接可以在在source指定執行

class UserInfo(models.Model):
    user_type_choices = (
        (1,'普通用戶'),
        (2,'VIP'),
        (3,'SVIP'),
    )
    user_type = models.IntegerField(choices=user_type_choices)

    username = models.CharField(max_length=32,unique=True)
    password = models.CharField(max_length=64)


#視圖
ret=models.UserInfo.objects.filter(pk=1).first()
aa=ret.get_user_type_display()

#serializer
xx=serializers.CharField(source='get_user_type_display')

rest-framework序列化之ModelSerializer

urls.py

"""
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^books/(?P<id>\d*)',views.Book.as_view())
]

models.py

from django.db import models


# Create your models here.


class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8, decimal_places=2)
    publish_time = models.DateTimeField(auto_now_add=True)  # 自動添加創建時間
    authors = models.ManyToManyField('Author')
    publish = models.ForeignKey('Publish')  # 一對多
    
    def test(self):
        return self.title+'>>'+str(self.price)


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    authordetail = models.OneToOneField('AuthorDetail')


class AuthorDetail(models.Model):
    tel_num = models.BigIntegerField()
    addr = models.CharField(max_length=32)


class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)
    email = models.EmailField()

"""
序列化的類
"""

# -*- coding: utf-8 -*-

#  想序列化Book 就要給其寫一個序列化的類
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

# class BookSerializer(serializers.Serializer):
#     id = serializers.CharField()
#     title = serializers.CharField()
#     price = serializers.CharField()
#     publish = serializers.CharField()  # 不使用source的時候,可以與表中的字段名相同
#     publish1 = serializers.CharField(source='publish')  # 字段名不能與前面的序列化的名字一樣, 在使用source的時候
#     publish_name = serializers.CharField(source='publish.name')  # 跨表獲取字段屬性的值
#     publish_pk = serializers.CharField(source='publish.pk')  # 跨表
#     # test1 = serializers.CharField(source='test')  # 方法
#
#     # 支持寫方法,如下:
#     # 方法一定要傳一個參數,是當前被序列化的book對象
#     publish_dic = serializers.SerializerMethodField()
#
#     def get_publish_dic(self, obj):
#         # 這里的obj就是當前book對象
#         return {'id': obj.publish.id, 'name': obj.publish.name}


from app01 import models


class AuthorSerializer(serializers.Serializer):
    id = serializers.CharField()
    name = serializers.CharField()
    age = serializers.CharField()


# ModelSerializer  是與表模型綁定的 Serializer
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        # 指定表模型
        model = models.Book
        fields = '__all__'  # 表示我要序列化所有字段
        #
        # 只序列化 title 和 id 兩個字段
        # fields = ['title','id']
        
        # 其他字段都需要 ,剔除price字段
        # exclude = ['price']  # 該方法和 fields 不能一起用
        
        # 如果想讓publish字段顯示出版社的名字
        # 跨表深度(連表的深度) 不建議使用,因為下幾層的參數無法控制,官方建議不超過十層,實際使用不要超過3
        depth = 1
    
    # publish = serializers.CharField(source='publish.name')
    authors = serializers.SerializerMethodField()
    
    def get_authors(self, obj):
        authors_list = obj.authors.all()
        authors_serializer = AuthorSerializer(authors_list, many=True)
        return authors_serializer.data
    title = serializers.CharField(max_length=6,min_length=3,error_messages={'max_length':'太長了','min_length':'你太短了'})
    # 局部鈎子
    # from rest_framework.exceptions import ValidationError --->導入報錯信息
    def validate_title(self, value):
        print(value) # 是 title 說對應的值
        if value.startswith('sb'):
            raise ValidationError('不能以sb開頭')
        return value
    
    # 全局鈎子
    def validate(self, attrs):
        print(attrs)  # 這里的attrs 是一個字典  {'title': 'bbb123', 'price': '999.12', 'authors': 2, 'publish': 2}
        if attrs.get('title').startswith('bbb')and attrs.get('price')>120:
            raise ValidationError('太貴啦,bbb書籍')
        return attrs
"""
views.py
"""

from django.shortcuts import render
from django.http.response import JsonResponse

# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
from app01 import models
from app01.myser import BookSerializer


class Book(APIView):
    # get 獲取所有書籍信息
    def get(self, request, id):
        response = {'status': 100, 'msg': '成功'}
        print(id)
        if not id:
            book_list = models.Book.objects.all()
            # 第一個參數是要序列化的queryset對象,如果要序列化多條,必須制定many=True
            # 當instance形參被傳入的實參是單個參數的時候,many=False
            book_serializer = BookSerializer(book_list, many=True)
        else:
            print(id)
            book_obj = models.Book.objects.filter(pk=id).first()
            book_serializer = BookSerializer(book_obj, many=False)
        print(book_serializer.data)
        response['books'] = book_serializer.data
        return Response(response)
    
    def post(self, request, id):
        response = {'status': 100, 'msg': '成功'}
        # 提交的字典
        book = request.data
        # 傳統方法,創建對象保存
        print(book)
        
        # 新方法,通過序列化組件保存,必須繼承自ModelSerializer
        book_ser = BookSerializer(data=book)
        # is_valid 提交的字段校驗通過
        if book_ser.is_valid():
            book_ser.save()
            response['book'] = book_ser.data
        else:
            response['msg'] = book_ser.errors  # errors  是序列化類 中的鈎子函數 raise來的報錯信息
        return Response(response)
    
    def put(self, request, id):
        response = {'status': 100, 'msg': '修改成功'}
        if id:
            
            # 提交的字典
            book = request.data
            # 傳統方法,創建對象保存
            print(book)
            book_obj = models.Book.objects.filter(pk=id).first()
            
            # 新方法,通過序列化組件保存,必須繼承自ModelSerializer
            book_ser = BookSerializer(data=book, instance=book_obj)
            # is_valid 提交的字段校驗通過
            if book_ser.is_valid():
                # 這里save()做修改
                book_ser.save()
                response['book'] = book_ser.data
            else:
                response['msg'] = book_ser.errors
        else:
            response['msg'] = '修改對象不存在'
        return Response(response)
    
    def delete(self, request, id):
        models.Book.objects.filter(pk=id).delete()
        response = {'status': 100, 'msg': '刪除成功'}
        return Response(response)


免責聲明!

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



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