有的时候序列化出来的字段并不是我们想要的, 比如说返回的用户 id,而我们想要返回的是用户名, 这个时候可以用到 django rest framework 的自定义字段功能。

先看一下原始数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
"id": 1,
"name": "1",
"desc": "sdg",
"user": 1
},
{
"id": 5,
"name": "1",
"desc": "sdg",
"user": 2
}
]

这里 user 显示的是 id, 并不是我们想要的 username

增加一个字段, 显示 username

models:

1
2
3
4
5
6
7
8
from django.db import models


# Create your models here.
class Game(models.Model):
name = models.CharField(verbose_name='游戏名字', max_length=10)
desc = models.CharField(verbose_name='描述', max_length=20)
user = models.ForeignKey(to='auth.User', on_delete=models.CASCADE)

serializers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from rest_framework import serializers
from .models import Game
from django.contrib.auth.models import User


class GameSerializer(serializers.ModelSerializer):

# 这里使用StringRelatedField来获取系统自带用户的username(依赖于models里面定义个__str__方法), 详情见下图
user_val = serializers.StringRelatedField(source='user', read_only=True, )

class Meta:
model = Game
fields = '__all__'
# exclude = ('user',)

# 如果不需要user字段, 下面可以去掉, 上面exclude = ('user',)
extra_kwargs = {
"user": {"read_only": True}
}

image.png

views:

1
2
3
4
5
6
7
class GameList(generics.ListCreateAPIView):
queryset = Game.objects.all()
serializer_class = GameSerializer

# 这里重写了perform_create, 保存数据的时候, user使用当前登录的用户.
def perform_create(self, serializer):
serializer.save(user=self.request.user)

返回结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[
{
"id": 1,
"user_val": "iuxt",
"name": "1",
"desc": "sdg",
"user": 1
},
{
"id": 5,
"user_val": "test",
"name": "1",
"desc": "sdg",
"user": 2
}
]

返回用户的多个字段

首先需要自定义一个序列化器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from rest_framework import serializers
from .models import Game
from django.contrib.auth.models import User


# 自定义一个序列化, 使用django 自带的user 模型类
class CustomUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', 'email'] # 指定序列化的字段


class GameSerializer(serializers.ModelSerializer):
class Meta:
model = Game
fields = '__all__'
# exclude = ('user',)

extra_kwargs = {
"user": {"read_only": True}
}

def to_representation(self, instance):
representation = super(GameSerializer, self).to_representation(instance)
# 这里修改user字段, 使用自定义序列化器.
# 获取多个属性
representation['user'] = CustomUserSerializer(instance.user, context=self.context).data

# 或者获取其中的某一个值
# representation['user'] = CustomUserSerializer(instance.user, context=self.context).data.get('username')
return representation

这个时候返回结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[
{
"id": 1,
"name": "1",
"desc": "sdg",
"user": {
"username": "iuxt",
"email": "iuxt@qq.com"
}
},
{
"id": 5,
"name": "1",
"desc": "sdg",
"user": {
"username": "test",
"email": "test@qq.com"
}
}