问题
this is a follow-up to this question I had here.
I can now POST a new AP object using user Primary Key and after commenting this line in the AP serializer user = UserIndexSerializer()
:
Postman request:
{
"user":1,
"name":"Max AP 05"
}
However the problem that I now have is that the initial UserIdexSerializer is rendered useless.
This serializer determines the fields to show in a GET request but in consequence imposes the fields required in a POST request. What I'm trying to do is:
- POST a new AP object only using the user ID
- Show the UserIndexSerializer fields during a GET request (first_name, last_name, but not the ID)
How can I make this work?
I have found and read this post.
I tried using different views, one for listing my models and one for creating a new one:
from rest_framework import serializers
from ..models.model_art_piece import AP
from .serializers_user import *
class APIndexSerializer(serializers.ModelSerializer):
user = UserIndexSerializer()
class Meta:
model = AP
fields = [
'id',
'user',
'name'
]
class APCreateSerializer(serializers.ModelSerializer):
user = UserIDSerializer()
class Meta:
model = AP
fields = [
'id',
'user',
'name'
]
def create(self, validated_data):
ap = AP.objects.create(**validated_data)
return ap
class APDetailsSerializer(serializers.ModelSerializer):
class Meta:
model = AP
fields = '__all__'
And I also tried creating different serializers:
from rest_framework import serializers
from ..models.model_user import User
class UserIndexSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
'first_name',
'last_name'
]
class UserIDSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [
'id'
]
class UserDetailsSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
This has not work at all, can anyone help me out with this?
回答1:
If I understood correctly what you want is to get the nested object during get. I had the same problem which I resolved with this in my serializer.
class APIndexSerializer(serializers.ModelSerializer):
class Meta:
model = AP
fields = ['id','user','name']
def to_representation(self, obj):
self.fields['user'] = UserIndexSerializer()
return super(APIndexSerializer, self).to_representation(obj)
You can with this create with id and get with nested information of user.
回答2:
I will give you an example to explain how to use different serializers in GET/POST for relational fields.
There is a Ticket model and it has a foreign key refers to User model. In your POST to create a ticket, you wanna user's id to create the object. In your GET to get ticket's details, you wanna show the user's details rather than ids.
Ticket(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
In your serializer file, you then have
class UserDetailSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('first_name', 'last_name')
class TicketPostSerializer(serializer.ModelSerializer):
class Meta:
model = Ticket
fields = '__all__'
class TicketDetailSerializer(serializer.ModelSerializer):
user = UserDetailSerializer(read_only=True)
class Meta:
model = Ticket
fields = '__all__'
Then, in Ticket's view function, you then have:
class TicketViewSet(viewsets.ModelViewSet):
serializer_class = TicketPostSerializer
def get_serializer_class(self):
if self.action in ['list', 'retrieve']:
return TicketDetailSerializer
All set, you are free to go.
来源:https://stackoverflow.com/questions/60600453/django-nested-objects-different-serializers-get-and-post