如何覆盖随响应 django rest 框架序列化程序返回的返回的序列化程序对象
how to override returned serializer object that is returned with the response django rest framework serializer
我有一个 Django 休息框架项目。当发出获取请求以显示与数据库结构不相似的特定方式时,我想覆盖 returned json 对象结构。
我当前的return对象显示如下:
{
"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'
person 字段是用户的外键。
我认为你可以使用模型方法。示例:
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')
希望对您有所帮助:
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
我的建议是不要覆盖序列化程序。序列化程序应该只按原样序列化您拥有的数据。在您的情况下,您可以创建一个 ViewSet(而不是 ModelViewSet),在 retrieve() 方法中使用过滤器定义您的查询,然后轻松配置您需要的响应。
我认为这对你有帮助:
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
}
我有一个 Django 休息框架项目。当发出获取请求以显示与数据库结构不相似的特定方式时,我想覆盖 returned json 对象结构。
我当前的return对象显示如下:
{
"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'
person 字段是用户的外键。
我认为你可以使用模型方法。示例:
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')
希望对您有所帮助:
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
我的建议是不要覆盖序列化程序。序列化程序应该只按原样序列化您拥有的数据。在您的情况下,您可以创建一个 ViewSet(而不是 ModelViewSet),在 retrieve() 方法中使用过滤器定义您的查询,然后轻松配置您需要的响应。
我认为这对你有帮助:
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
}