日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Django框架深入了解_02(DRF之序列化、反序列化)

發布時間:2024/9/30 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Django框架深入了解_02(DRF之序列化、反序列化) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

閱讀目錄

序列化:將Python對象準換成json格式的字符串,反之即為反序列化

DRF的序列化使用過程:

使用drf的序列化組件
-1 新建一個序列化類繼承Serializer
-2 在類中寫要序列化的字段

-在視圖中使用序列化的類
-1 實例化序列化的類產生對象,在產生對象的時候,傳入需要序列化的對象(queryset)
-2 對象.data
-3 return Response(對象.data)

使用示例:

新建Django項目:settings.py文件注冊rest_framework,使用MySQL數據庫創建數據

-------------------------------------------------------------------- 注:如果你對python感興趣,我這有個學習Python基地,里面有很多學習資料,感興趣的+Q群:895817687 --------------------------------------------------------------------# settings.py DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'drf_ser01','HOST': '127.0.0.1','PORT': 3306,'USER': 'root','PASSWORD': '123'} }# __init__.py import pymysql pymysql.install_as_MySQLdb() from django.db import models# Create your models here.class Book(models.Model):title = models.CharField(max_length=32)price = models.DecimalField(decimal_places=1, max_digits=6)publish = models.ForeignKey(to='Publish')author = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book', 'author'))class Publish(models.Model):name = models.CharField(max_length=32)addr = models.CharField(max_length=64, null=True)class Author(models.Model):name = models.CharField(max_length=32)age = models.IntegerField()class Book2Author(models.Model):book = models.ForeignKey(to='Book')author = models.ForeignKey(to='Author')

app01新建MySer.py

# 先創建一個BookSer序列化類 from rest_framework import serializersclass BookSer(serializers.Serializer):id = serializers.CharField()title = serializers.CharField()publish = serializers.CharField()author = serializers.CharField()

app01視圖函數views.py中

from django.shortcuts import render,HttpResponse,redirect from app01.MySer import BookSer from rest_framework.response import Response from rest_framework.views import APIView from app01 import models# Create your views here.class Books(APIView):response = {'code': 100, 'msg': '查詢成功'}def get(self, request):books = models.Book.objects.all()books_ser = BookSer(instance=books, many=True)return Response(books_ser.data)

配路由:

from django.conf.urls import url from django.contrib import admin from app01 import viewsurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^books/', views.Books.as_view()), ]

(通過NaviCat創建圖書數據,用于查詢…)

使用Postman發送get請求,獲取到數據庫中所有圖書信息
可以看出一對多和多對多的外鍵字段顯示的是對象名字,下面進一步使用序列化,讓信息顯示更完善

-source:可以指定字段(name publish.name),可以指定方法-SerializerMethodField搭配方法使用(get_字段名字) publish_detail=serializers.SerializerMethodField(read_only=True) def get_publish_detail(self,obj):return {'name':obj.publish.name,'city':obj.publish.city}

更新版本BookSer

from rest_framework import serializersclass BookSer(serializers.Serializer):id = serializers.CharField()title = serializers.CharField()publish = serializers.CharField(source='publish.name')author = serializers.SerializerMethodField()def get_author(self, obj):authors = []for author_obj in obj.author.all():authors.append({'name': author_obj.name, 'age': author_obj.age})return authors


補充:

-read_only:反序列化時,不傳
-write_only:序列化時,不顯示

以上是序列化的一種方式

下面看看序列化的另外一種方式:ModelSerializers:指定了表模型

class Meta:model=表模型#要顯示的字段fields=('__all__')fields=('id','name')#要排除的字段exclude=('name')#深度控制depth=1-重寫某個字段在Meta外部,重寫某些字段,方式同Serializers # 序列化方式二: class BookSer(serializers.ModelSerializer):class Meta:model = models.Bookfields = ('__all__')


如果只想取其中幾個字段,可以進行指定:

# 序列化方式二: class BookSer(serializers.ModelSerializer):class Meta:model = models.Bookfields = ['id', 'title']# fields = ('__all__')


剛才看到__all__,序列化所有字段,查詢到的數據里面publish和author都是對應id值,如果需要獲取到對應publish和author的關聯信息,可以在BookSer內,Meta外重新寫字段,方式同serializers

# 序列化方式二: class BookSer(serializers.ModelSerializer):class Meta:model = models.Book# fields = ['id', 'title']fields = ('__all__')publish = serializers.CharField(source='publish.name')author = serializers.SerializerMethodField()def get_author(self, obj):authors = []for author_obj in obj.author.all():authors.append({'name': author_obj.name, 'age': author_obj.age})return authors


改進:

class AuthorSer(serializers.Serializer):id = serializers.CharField()name = serializers.CharField()age = serializers.CharField()# 序列化方式二改進: class BookSer(serializers.ModelSerializer):class Meta:model = models.Book# fields = ['id', 'title']fields = ('__all__')publish = serializers.CharField(source='publish.name')author = serializers.SerializerMethodField()def get_author(self, obj):ret = AuthorSer(obj.author.all(), many=True) return ret.data


通過post請求新增數據:
對數據進行新增使用反序列化實現,這里反序列化有2種情況進行新增:

使用繼承了Serializers序列化類的對象,反序列化(需重寫create方法)

from django.db import models# Create your models here.class User(models.Model):name = models.CharField(max_length=32)password = models.CharField(max_length=64)choices = (('1', 'Super_Admin'), ('2', 'General_Admin'), ('3', 'General_User') )user_type = models.CharField(max_length=6, choices=choices, default='3')class Book(models.Model):title = models.CharField(max_length=32)price = models.DecimalField(decimal_places=1, max_digits=6)publish = models.ForeignKey(to='Publish', null=True)author = models.ManyToManyField(to='Author')class Publish(models.Model):name = models.CharField(max_length=32)addr = models.CharField(max_length=64, null=True)class Author(models.Model):name = models.CharField(max_length=32)age = models.IntegerField() class Book(APIView):def post(self, request):response = {'code': 100, 'msg': '新增成功'}# 使用繼承了Serializers序列化類的對象,反序列化book = BookSer(data=request.data)if book.is_valid():# 清洗通過的數據,需要在MySer.py中重寫createbook.create(book.validated_data)return Response(response) # MySer.pyclass BookSer(serializers.Serializer):# read_only 反序列化的時候,該字段不傳# 這里id可以不傳自增,publish、author不傳,當然需要在models里面把不傳字段設置為null=True# author多對多字段不能設置null=Trueid = serializers.CharField(read_only=True) title = serializers.CharField()price = serializers.CharField()publish = serializers.CharField(source='publish.id', read_only=True)author = serializers.SerializerMethodField(read_only=True)def get_author(self, obj):ret = AuthorSer(obj.author.all(), many=True)return ret.data# 重寫create方法,才能在使用Serializer發序列化方法進行新增數據def create(self, validated_data):res = models.Book.objects.create(**validated_data)return res

使用繼承了ModelSerializers序列化類的對象,反序列化

from django.db import models# Create your models here.class User(models.Model):name = models.CharField(max_length=32)password = models.CharField(max_length=64)choices = (('1', 'Super_Admin'), ('2', 'General_Admin'), ('3', 'General_User') )user_type = models.CharField(max_length=6, choices=choices, default='3')class Book(models.Model):title = models.CharField(max_length=32)price = models.DecimalField(decimal_places=1, max_digits=6)publish = models.ForeignKey(to='Publish', null=True)author = models.ManyToManyField(to='Author')class Publish(models.Model):name = models.CharField(max_length=32)addr = models.CharField(max_length=64, null=True)class Author(models.Model):name = models.CharField(max_length=32)age = models.IntegerField() class BookSer(serializers.ModelSerializer):class Meta:model = models.Bookfields = "__all__" class Book(APIView):def post(self, request):response = {'code': 100, 'msg': '新增成功'}# 使用繼承了ModelSerializers序列化類的對象,反序列化book_ser = BookSer(data=request.data)if book_ser.is_valid():book_ser.save()else:response['error'] = book_ser.errors['name'][0]return Response(response)

使用ModelSerializer反序列化save數據后,多對多關聯的那張表也會自動關聯產生新的數據。

局部校驗和全局校驗

# MySer.pyfrom rest_framework.exceptions import ValidationError class BookSer(serializers.ModelSerializer):class Meta:model = models.Bookfields = "__all__"def validate_title(self, value):if value.startswith('sb'):raise ValidationError('不能以sb開頭')return valuedef validate(self, attrs):title = attrs.get('title')price = attrs.get('price')if title.startswith('禁書') or int(price) <= 15:raise ValidationError('書名或價格不正常')return attrs

總結:

-反序列化的校驗
-validate_字段名(self,value):
-如果校驗失敗,拋出ValidationError(拋出的異常信息需要去bookser.errors中取)
-如果校驗通過直接return value
-validate(self,attrs)
-attrs所有校驗通過的數據,是個字典
-如果校驗失敗,拋出ValidationError
-如果校驗通過直接return attrs

總結

以上是生活随笔為你收集整理的Django框架深入了解_02(DRF之序列化、反序列化)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。