如何覆盖随响应Django Rest Framework序列化程序返回的返回序列化程序对象

时间:2019-07-10 21:30:28

标签: django django-rest-framework django-views django-serializer

我有一个django rest框架项目。当要获取显示与数据库结构不同的特定方法的获取请求时,我想覆盖返回的json对象结构。

我当前的返回对象显示如下:

    {
        "id": 9,
        "namespace": "steve",
        "path": "something/another",
        "value": "this is a value",
        "person": 1
    },
    {
        "id": 11,
        "namespace": "namespace1",
        "path": "path2",
        "value": "anyoher value",
        "person": 2
    },
    {
        "id": 12,
        "namespace": "namespace1",
        "path": "path3",
        "value": "this dsiaalks",
        "person": 2
    },
    {
        "id": 13,
        "namespace": "namespace2",
        "path": "path4",
        "value": "asdfasdfasdf",
        "person": 2
    },

我要切换

"person":2 

显示

"user":{
    "userId":testUser
}
  • testUser是ID为2 *的用户的用户名。

这是我目前的小摩托车:

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


class PreferenceSerializer(serializers.ModelSerializer):
    person = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(),)

    class Meta:
        model = Preference
        fields = ('id', 'namespace', 'path', 'value', 'person')

这是当前模型:

from django.db import models
from django.contrib.auth.models import User
from owf_framework.people.models import Person

class Preference(models.Model):
    id = models.BigAutoField(primary_key=True, null=False)
    version = models.BigIntegerField(default=1, null=False)
    path = models.CharField(max_length=200, null=False)
    namespace = models.CharField(max_length=200, null=False)
    value = models.TextField(null=False)
    user_id = models.BigIntegerField(null=False, default=1)
    person = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.namespace

    class Meta:
        db_table = 'preference'

现场人员是用户的外键。

4 个答案:

答案 0 :(得分:1)

希望这会有所帮助:

  

serializers.py

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


class PreferenceSerializer(serializers.ModelSerializer):
    person = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(),)

    class Meta:
        model = Preference
        fields = ('id', 'namespace', 'path', 'value', 'person')

    def to_representation(self, instance):
        ret = super(PreferenceSerializer, self).to_representation(instance)
        # check the request is list view or detail view
        is_list_view = isinstance(self.instance, list)
        if is_list_view:
            person_id = ret.pop('person', None)
            user_obj = User.objects.filter(id=person_id).first()
            user_name = user_obj.username if user_obj else ""
            extra_ret = {
                "user": {
                    "userId": user_name
                }
            }
            ret.update(extra_ret)
        return ret

答案 1 :(得分:0)

我认为您可以使用模型方法。例如:

models.py

from django.db import models
from django.contrib.auth.models import User
from owf_framework.people.models import Person

class Preference(models.Model):
    id = models.BigAutoField(primary_key=True, null=False)
    version = models.BigIntegerField(default=1, null=False)
    path = models.CharField(max_length=200, null=False)
    namespace = models.CharField(max_length=200, null=False)
    value = models.TextField(null=False)
    user_id = models.BigIntegerField(null=False, default=1)
    person = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.namespace

    def get_person(self):
        return self.person.username

    class Meta:
        db_table = 'preference'

然后在您的序列化器中:

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


class PreferenceSerializer(serializers.ModelSerializer):
    person = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(),)

    class Meta:
        model = Preference
        fields = ('id', 'namespace', 'path', 'value', 'person', 'get_person')

答案 2 :(得分:0)

我的建议是不要覆盖序列化程序。序列化程序应该只按原样序列化您拥有的数据。在您的情况下,您可以创建一个 ViewSet(而不是 ModelViewSet),在retrieve() 方法中使用过滤器定义您的查询,然后轻松配置您需要的响应。

答案 3 :(得分:0)

我认为这对您有帮助:

from rest_framework.serializers import ModelSerializer, SerializerMethodField

class PrefrenceSerializer(ModelSerializer):
    user = SerializerMethodField()

    class Meta:
        model = Prefrence
        exclude = ['person']

    def get_user(self, obj):

        return {
            "userId": obj.person.userId
        }