_02(シリアライズのDRF、直列化復元)を理解するためのDjangoフレームワーク

シリアル化:Pythonオブジェクトの登録フォーマット文字列のJSONを交換、つまり、逆直列化復元に

プロセスの使用のDRFシーケンス:

DRFシリアライゼーションコンポーネントを使用
-1新しいクラスの配列はシリアライザ継承
シリアル化するクラスで-2-ライトフィールドを

-ビュークラスのシーケンス用いて
オブジェクトのクラスの1例のシーケンスを生成し、オブジェクトが生成されます際に必要と着信シリアル化されたオブジェクト(クエリセット)
-2 .DATAオブジェクト
応答(オブジェクト.DATA)を返す-3

使用例:

新しいDjangoプロジェクト:settings.pyファイル登録 rest_framework、MySQLデータベースを使用してデータを作成します

#のsettings.pyの 
DATABASES = {
     ' デフォルト' {
         ' ENGINE '' django.db.backends.mysql ' ' NAME '' drf_ser01 ' ' ホスト'' 127.0.0.1 ' ' PORT ':3306 ' USER '' ルート' "PASSWORD "' 123 ' 
    } 
} 

__init__.pyの
インポートpymysql 
pymysql.install_as_MySQLdb()
MySQLデータベースの接続
django.db 輸入モデル

#は、ここにあなたのモデルを作成します。


クラスブック(models.Model):
    タイトル = models.CharField(max_lengthを= 32 
    価格 = models.DecimalField(decimal_places = 1、max_digits = 6 
    公開 = models.ForeignKey(=に' 公開' 
    の著者 = models.ManyToManyField( =に' 著者' =通じ、' Book2Author '、through_fieldsは=(' ブック'' 著者' ))


クラス(models.Model)公開: = models.CharField(max_lengthを= 32 
    のaddr = models.CharField(max_lengthを= 64、ヌル= 真)


クラスの著者(models.Model):
    名前 = models.CharField(max_lengthを= 32 
    、年齢 = models.IntegerField()


クラスBook2Author(models.Model):
    書籍(=へ= models.ForeignKey ' ブック' 
    の著者(=へ= models.ForeignKey ' 著者'
モデル

app01新MySer.py

先创建一个BookSer序列化类
から rest_framework インポートシリアライザ


クラスBookSer(serializers.Serializer):
    ID = serializers.CharField()
    タイトル = serializers.CharField()
    発行 = serializers.CharField()
    著者 = serializers.CharField()

views.pyでapp01ビュー機能

django.shortcuts インポート、レンダリングのHttpResponse、リダイレクト
 から app01.MySerの輸入BookSer
 から rest_framework.responseの輸入レスポンス
 から rest_framework.viewsの輸入APIView
 から app01 輸入モデル

#がここにあなたの意見を作成します。

クラス書籍(APIView):
    応答 = { ' コード' 100、' MSG '' 查询成功' }
     DEF (自己、リクエスト)を得ます。
        書籍 =models.Book.objects.all()
        books_ser = BookSer(例えば=書籍、多くの= 真)
         の戻り応答(books_ser.data)

ルーティングと:

django.conf.urls インポートURLを
 から django.contribの輸入管理者
 から app01 インポートビュー


urlpatterns = [ 
    URL(R ' ^管理/ ' 、admin.site.urls)、
    URL(R ' ^ブック/ ' 、views.Books。 as_view())
]

(書籍照会するためのNavicatで作成したデータを、...)

すべての書籍のデータベースに情報を取得するために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 serializers


class 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.Book
        fields = ('__all__')

如果只想取其中几个字段,可以进行指定:

# 序列化方式二:
class BookSer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = ['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中重写create
            book.create(book.validated_data)
        return Response(response)
# MySer.py

class BookSer(serializers.Serializer):
    # read_only 反序列化的时候,该字段不传
    # 这里id可以不传自增,publish、author不传,当然需要在models里面把不传字段设置为null=True
    # author多对多字段不能设置null=True
    id = 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.Book
        fields = "__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.py

from rest_framework.exceptions import ValidationError
class BookSer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = "__all__"

    def validate_title(self, value):
        if value.startswith('sb'):
            raise ValidationError('不能以sb开头')
        return value

    def 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

 

 

おすすめ

転載: www.cnblogs.com/suguangti/p/11123781.html