Python Django Rest序列化程序:在GET上使用嵌套序列化程序,但不在POST上使用
问题如下:在下面的代码中,我有一个Python Django Rest序列化程序:在GET上使用嵌套序列化程序,但不在POST上使用,python,django,serialization,django-rest-framework,Python,Django,Serialization,Django Rest Framework,问题如下:在下面的代码中,我有一个PreguntaSerializer。现在,如果我发布一个JSON,代码如下: { "categoria_pregunta": 1, "titulo": "Pregunta de Prueba", "descripcion": "Esta es la pregunta que mando por Postman", "persons": [1, 3, 5, 3050] } 一切都正常,但当我检索数据时,我得到的是categori
PreguntaSerializer
。现在,如果我发布一个JSON,代码如下:
{
"categoria_pregunta": 1,
"titulo": "Pregunta de Prueba",
"descripcion": "Esta es la pregunta que mando por Postman",
"persons": [1, 3, 5, 3050]
}
一切都正常,但当我检索数据时,我得到的是categoria\u pregunta
和persons
,与我发布它们的方式相同(分别为int和array)。我希望能够使用Categoria\u preguntaSerializer
和PersonForPreguntaSerializer
获取这些字段,但是如果我在preguntaSerializer
中为他们各自的序列化程序更改Categoria\u preguntaSerializer
中的persons
,我会在发布前面提到的JSON时出错。
是否有一种方法可以对这两个操作使用相同的PreguntaSerializer
,还是应该将GET
和POST
的视图分开,并使用不同的序列化器
型号.py
class Categoria_pregunta(models.Model):
nombre = models.CharField(
'Descripcion', null=True, blank=True, max_length=150, default='')
status = models.IntegerField(
'Estado', null=True, blank=True, choices=STATUS_CHOICES)
class Pregunta(models.Model):
titulo = models.CharField(max_length=200, null=False, blank=False, default='')
descripcion = models.TextField(null=False, blank=False)
categoria_pregunta = models.ForeignKey(
Categoria_pregunta, null=True, blank=False, max_length=20)
usuario = models.ForeignKey(User, null=True, blank=False, max_length=20)
persons = models.ManyToManyField(Person, blank=False, max_length=20)
class Person(models.Model):
name = models.CharField('Nombre', null=True,
blank=False, max_length=1000, default='')
lastname = models.CharField(
'Apellido', null=True, blank=False, max_length=1000, default='')
...
序列化程序.py
class Categoria_pregunta(models.Model):
nombre = models.CharField(
'Descripcion', null=True, blank=True, max_length=150, default='')
status = models.IntegerField(
'Estado', null=True, blank=True, choices=STATUS_CHOICES)
class Pregunta(models.Model):
titulo = models.CharField(max_length=200, null=False, blank=False, default='')
descripcion = models.TextField(null=False, blank=False)
categoria_pregunta = models.ForeignKey(
Categoria_pregunta, null=True, blank=False, max_length=20)
usuario = models.ForeignKey(User, null=True, blank=False, max_length=20)
persons = models.ManyToManyField(Person, blank=False, max_length=20)
class Person(models.Model):
name = models.CharField('Nombre', null=True,
blank=False, max_length=1000, default='')
lastname = models.CharField(
'Apellido', null=True, blank=False, max_length=1000, default='')
...
视图.py
class Categoria_pregunta(models.Model):
nombre = models.CharField(
'Descripcion', null=True, blank=True, max_length=150, default='')
status = models.IntegerField(
'Estado', null=True, blank=True, choices=STATUS_CHOICES)
class Pregunta(models.Model):
titulo = models.CharField(max_length=200, null=False, blank=False, default='')
descripcion = models.TextField(null=False, blank=False)
categoria_pregunta = models.ForeignKey(
Categoria_pregunta, null=True, blank=False, max_length=20)
usuario = models.ForeignKey(User, null=True, blank=False, max_length=20)
persons = models.ManyToManyField(Person, blank=False, max_length=20)
class Person(models.Model):
name = models.CharField('Nombre', null=True,
blank=False, max_length=1000, default='')
lastname = models.CharField(
'Apellido', null=True, blank=False, max_length=1000, default='')
...
我建议有两个不同的字段用于读写。您可以在序列化程序
persons\u data
中添加一个新字段,用于获取序列化格式的人员数据列表
示例代码:
class PreguntaSerializer(serializers.ModelSerializer):
usuario = UserSerializer(read_only=True)
categoria_pregunta = serializers.PrimaryKeyRelatedField(queryset=Categoria_pregunta.objects.all())
persons_data = PersonForPreguntaSerializer(source='persons', many=True, read_only=True)
class Meta:
model = Pregunta
exclude = ('status', )
由于您正在Meta
类中使用exclude
,persons
字段将已包含在读写中,该字段将接受您在请求json中传递的主键ID列表
您还可以查看序列化程序的.to_representation()
和.to_internal_value()
方法
从文件
.to_representation()
-重写此项以支持序列化,用于读取操作。
.to_internal_value()
-重写此选项以支持写操作的反序列化
您应该重写
到_representation()
方法试试这个,
from rest_framework.serializers import Serializer
class PreguntaSerializer(serializers.ModelSerializer):
usuario = UserSerializer(read_only=True)
categoria_pregunta = serializers.PrimaryKeyRelatedField(queryset=Categoria_pregunta.objects.all())
persons = serializers.PrimaryKeyRelatedField(many=True, queryset=Person.objects.all())
class Meta:
model = Pregunta
fields = '__all__'
def to_representation(self, instance):
if self.context['request'].method == 'POST':
user = UserSerializer(instance.usuario).data
categoria_pregunta = Categoria_preguntaSerializer(instance.categoria_pregunta).data
persons = PersonForPreguntaSerializer(instance.persons, many=True).data
data = {"id": instance.id,
"usuario": user,
"categoria_pregunta": categoria_pregunta,
"persons": persons,
"titulo": instance.titulo,
"descripcion": instance.descripcion
}
return data
return Serializer.to_representation(self, instance)
您可以添加您的
视图.py
?这个答案有效。我只是想保持字段名的一致性,而另一个答案正好说明了这一点。