最近写到rest_framework返回数据,需求有正向的数据关联反向的数据关联,以及没有关系的两个表之间的数据关联起来一起返回出去
class User(models.Model):
username = models.CharField(max_length=50, default='可爱', editable=False, verbose_name='昵称')
status = models.BooleanField(default=0, choices=((0, '未关注'), (1, '已关注')), verbose_name='是否关注')
level_id = models.ForeignKey(to='Level', blank=True, null=True, default=None, on_delete=models.SET_NULL, verbose_name='用户等级')
addtime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
class Level(models.Model):
name = models.CharField(max_length=50, editable=False, verbose_name='级别')
- 正向关联的使用 (序列化器使用的serializers.ModelSerializer)
class UserSerializer(serializers.ModelSerializer):
"""用户数据序列化"""
addtime = serializers.DateTimeField(read_only=True, format="%Y-%m-%d %H:%M:%S")
status = serializers.CharField(source='get_status_display')
level_id_icon = serializers.CharField(source='level_id.name')
class Meta:
model = User
fields = '__all__'
- 反向关联的使用 (序列化器使用的serializers.ModelSerializer)
class LevelSerializer(serializers.ModelSerializer):
"""用户数据序列化"""
"""
level_id = models.ForeignKey(to='Level', related_name='levels', blank=True, null=True, default=None, on_delete=models.SET_NULL, verbose_name='用户等级')
"""
levels = UserSerializer(many=True, read_only=True)
class Meta:
model = Level
fields = '__all__'
- 无关联表的序列化器使用 (序列化器使用的serializers.ModelSerializer)
这个时候我们需要依赖强大的第三方包 django-rest-mutiple-models
pip install django-rest-multiple-models
INSTALLED_APPS = (
....
'drf_multiple_model',
)
from drf_multiple_model.views import ObjectMultipleModelAPIView
class Play(models.Model):
genre = models.CharField(max_length=100)
title = models.CharField(max_length=200)
pages = models.IntegerField()
class Poem(models.Model):
title = models.CharField(max_length=200)
style = models.CharField(max_length=100)
lines = models.IntegerField()
stanzas = models.IntegerField()
class PlaySerializer(serializers.ModelSerializer):
class Meta:
model = Play
fields = ('genre','title','pages')
class PoemSerializer(serializers.ModelSerializer):
class Meta:
model = Poem
fields = ('title','stanzas')
class LimitPagination(MultipleModelLimitOffsetPagination):
default_limit = 10
from drf_multiple_model.viewsets import ObjectMultipleModelAPIViewSet
class TextAPIView(ObjectMultipleModelAPIView):
pagination_class = LimitPagination
querylist = [
{'queryset': Play.objects.all(), 'serializer_class': PlaySerializer},
{'queryset': Poem.objects.filter(style='Sonnet'), 'serializer_class': PoemSerializer},
....
- ObjectMultipleModelAPIView 的拓展
class TextAPIView(ObjectMultipleModelAPIView):
pagination_class = LimitPagination
def get(self, request, *args, **kwargs):
uid = request.GET.get('uid', '')
cid = request.GET.get('cid', '')
sid = request.GET.get('sid', '')
self.querylist = [
{'queryset': Student.objects.filter(id=uid).order_by('-id'),
'serializer_class': StudentSerializers, 'label': 'student', },
{'queryset': Student.objects.filter(id=uid).order_by('-id'),
'serializer_class': StudentSerializers, 'label': 'student', },
]
return self.list(request, *args, **kwargs)
- 有人问了,那么没有关联的表字段,要怎么加到一个序列化器中,以下是序列化器不使用外键进行序列化嵌套
class PoemSerializer(serializers.ModelSerializer):
book_id = serializers.SerializerMethodField()
class Meta:
model = Poem
fields = ('title', 'stanzas', 'book_id')
def get_book_id(self, obj):
user = book.objects.filter(id=obj.id).first()
if user:
data = user.name
else:
data = None
return data
- 这个方法是通过自定义一个键,通过get去拿到每个传进来的数据对象,使用SerializerMethodField进序列化关联, 参考 超链接 还有一种定义模型的方法 参考 超链接