DRF序列化程序类

时间:2015-08-18 17:34:11

标签: python django serialization django-rest-framework

在使用Django-Rest-Framework(DRF)开发网络API时,我遇到了一些麻烦。

问题陈述

我有两个模型UserReview

models.py

# Consider User model as `django.contrib.auth.models.User`
from django.contrib.auth.models import User
from django.db import models

# Review model
class Review(models.Model):
    head = models.CharField()
    content = models.CharField()
    user = models.ForeignKey(User)
    is_deleted = models.BooleanField(default=False)

并且,我有两个这样的端点:

    /users/      - list of all users
    /users/<pk>  - detail of user
    /review/     - list of all reviews
    /review/<pk> - detail of review

我希望我的输出像这样:

# /users/ 
[
    {
        "url": "http://localhost:8000/users/1",
        "fisrt_name": "Adolf",
        "last_name": "Hitler",
        "email": "adolfhilter@xyz.com",
        "is_staff": false
        ........ # other fields
    },
    .........
    .........
]

# /reviews/
[
    {
        "url": "http://localhost:8000/reviews/1",
        "head": "Head of Review",
        "content": "Content of Review",
        "user": {
            "url": "http://localhost:8000/users/1",
            "first_name": "Adolf",
            "last_name": "Hitler"
        },
        "is_deleted": false
    },
    .........
    .........
]

我的解决方案

为了实现这种形式的输出,我创建了三个序列化程序类,一个是UserSerializer类,第二个是ReviewSerializer,第一个是ReviewUserSerializer。这些类如下:< / p>

serializers.py

from rest_framework import serializers
from .models import Review
from django.contrib.auth.models import User

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'first_name', 'last_name', 'email', 'is_staff', .....)

class ReviewUserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'first_name', 'last_name')

class ReviewSerializer(serializers.HyperlinkedModelSerializer):
    user = ReviewUserSerializer()
    class Meta:
        model = Review
        fields = ('url', 'head', 'content', 'user')

所以,现在我想知道,

  

是否有其他方法可以避免为这些类型的情况创建额外的单独序列化程序类(此处为ReviewUserSerializer)?

如果是,请建议我使用正确的代码段解决方案。

1 个答案:

答案 0 :(得分:2)

您是否尝试过使用SerializerMethodField?

from rest_framework import serializers
from .models import Review
from django.contrib.auth.models import User

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('url', 'first_name', 'last_name', 'email', 'is_staff', .....)

class ReviewSerializer(serializers.HyperlinkedModelSerializer):
    user = serializers.SerializerMethodField(read_only=True)
    class Meta:
        model = Review
        fields = ('url', 'head', 'content', 'user')

    def get_user(self, obj) :
        request = self.context['request']
        return {
          'url': reverse('user-detail',
                       kwargs={'pk': obj.user.id}, request=request),
          'first_name': obj.user.first_name,
          'last_name': obj.user.last_name,
        }