django-rest-framework-02
常见问题以及使用技巧
-
问题:将字典类型数据传递给序列器,默认是需要传入所有非空字段的,如果只传入部分字段,将会出现错误
-
解决办法:数据传入序列器时添加partial参数True
-
例子:
serializer = CommentSerializer(comment, data={'content': u'foo bar'}, partial=True)
-
问题:ModelSerializer和Serializer的区别?
-
答:前者可以使用django中的Model类在models.py中编写模型,也可以在序列器中添加或者覆盖models.py中的字段,后者在序列器中使用Serializer.
编写模型 -
例子:
在序列器中编写数据模型
class CommentSerializer(serializers.Serializer): user = UserSerializer(required=False) # May be an anonymous user. content = serializers.CharField(max_length=200) created = serializers.DateTimeField()
在models.py中编写数据模型
class AdjustOrderSerializer(ModelSerializer): goodsmanage = GoodsManageSerizlizer(many=True) warehouse = WareHouseSerizlizer(many=True) supplier = SupplierSerizlizer(many=True) userprofile = UserProfileSerializers(many=True) # 添加models.py中没有的字段 test = Serializers.CharField(max_length=30) class Meta: model = AdjustOrder fields = 'all'
-
简单序列器的写法:不存在关联表的情况
class PurchaseTypeSerializer(ModelSerializer): class Meta: model = PurchaseType fields = 'all'
-
说明:重写Meta,model指定我们models.py中定义的模型类,fields指定序列器包含的模型类中的字段,这个值有几种写法:
- 1.fields = ['字段1', '字段2', ...]或者('字段1', 。。。)
- 2.fields = "--all--",表示所有字段,官网推荐这样写。
- 3.exclude = ('users',),用这个来代替fields, 表示排除这个字段,也是一种推荐的写法。
- 4.read_only_fields = (',,'...),指定只读字段。
-
序列器存在外键关系时的写法:在序列器中调用外键关联表的序列器,这个做法在官网文档被称作序列器的嵌套
-
如下所示:many=True表示序列器接收到的data是多个数据(字典),required=False表示序列器可以接收None
-
例子:
class CommentSerializer(serializers.Serializer): user = UserSerializer(required=False) edits = EditItemSerializer(many=True) # A nested list of 'edit' items. content = serializers.CharField(max_length=200) created = serializers.DateTimeField()
-
嵌套序列器中的create方法编写,关键参数“valited_data”,注释部分说明了内层和外层模型的增加方法
-
例子:
class UserSerializer(serializers.ModelSerializer): # 嵌套profile的序列器 profile = ProfileSerializer() class Meta: model = User fields = ('username', 'email', 'profile') def create(self, validated_data): # validtaed_data包含了user所有的字段以及关联表 profile_data = validated_data.pop('profile') # 外层序列器对应的表模型使用validated_data增加记录 user = User.objects.create(validated_data) # 内层序列器对应的表模型使用刚才从valited_data中取出的profile的数据字典增加记录 Profile.objects.create(user=user, profile_data) return user
- 嵌套序列器的update方法编写
方法一,普通写法
def update(self, instance, validated_data): profile_data = validated_data.pop('profile') # Unless the application properly enforces that this field is # always set, the follow could raise aDoesNotExist
, which # would need to be handled. profile = instance.profileinstance.username = validated_data.get('username', instance.username) instance.email = validated_data.get('email', instance.email) instance.save() profile.is_premium_member = profile_data.get( 'is_premium_member', profile.is_premium_member ) profile.has_support_contract = profile_data.get( 'has_support_contract', profile.has_support_contract ) profile.save() return instance
方法二,增加一个管理类(更推荐)
class UserManager(models.Manager): ... def create(self, username, email, is_premium_member=False, has_support_contract=False): user = User(username=username, email=email) user.save() profile = Profile( user=user, is_premium_member=is_premium_member, has_support_contract=has_support_contract ) profile.save() return user # ---------------接下来在序列类写------------- def create(self, validated_data): return User.objects.create( username=validated_data['username'], email=validated_data['email'] is_premium_member=validated_data['profile']['is_premium_member'] has_support_contract=validated_data['profile']['has_support_contract'] )
-
HyperLinkedSerializer类使用:
-
这个序列类作用是使用超链接来表示api,通常需要传入context={'request': request}这个参数来确保url绝对路径。
-
例子:
serializer = AccountSerializer(queryset, context={'request': request})
评论 2
这编辑器样式看着有点难受, 而且之后想修改根本没办法
可以更改的!
改不了, 点击编辑的时候有一堆标签,
感谢楼主分享!