0

I've got Membership class which contains 3 ForeginKey fields. These FK always have to reference to already existing objects so I'm wondering how simplify create and update methods inside MembershipSerializer in order to assign these fields using only keys passed in request.

Here's MembershipSerializer class code:

class MembershipSerializer(serializers.ModelSerializer):
user = UserSerializer(many=False)
club = ClubSerializer(many=False)
inClubRole = InClubRoleSerializer(many=False)
class Meta:
    fields=(
        'user',
        'club',
        'inClubRole',
        )

    model = Membership

def create(self, validated_data):
    print(validated_data)
    user_data = User.objects.get(id=validated_data.pop('user'))
    club_data = Club.objects.get(id=validated_data.pop('club'))
    inClubRole_data = InClubRole.objects.get(id=validated_data.pop('inClubRole'))
    instance = Membership.objects.create(**validated_data)
    instance.user=user_data
    instance.club = club_data
    instance.inClubRole = inClubRole_data
    return instance

Since User, Club, and InClubRole models already exists I want to simplify POST and UPDATE for Membership class just by passing Primary Keys like that:

{
"user": 1,
"club": 1,
"inClubRole": 4
}

However create methods still expects passing every field related with User, Club and InClubRole classes. How to fix that? Or maybe there is a simplier way to handle with it?

BaqBak
  • 15
  • 4

2 Answers2

1

You should be able to pass the arguments directly into the Membership.objects.create call:

def create(self, validated_data):
    return Membership.objects.create(
        **validated_data,
        user_id=validated_data.pop('user'),
        club_id=validated_data.pop('club'),
        inClubRole_id=validated_data.pop('inClubRole')
    )

I believe you can also get this to work by setting your fields as:

fields=('user_id', 'club_id', 'inClubRole_id')

and changing your JSON to:

{
  "user_id": 1,
  "club_id": 1,
  "inClubRole_id": 4
}
Youssef Moussaoui
  • 12,187
  • 2
  • 41
  • 37
  • Thanks, it works that way. However is it possible to keep Serializers functionality during _GET_ so I can fill my request with fields from Club,User, InClubRole ? – BaqBak Apr 30 '19 at 15:31
0

I've already handled with it a little bit different. I swapped ...Serializer fields to PrimaryKeyRelatedField so I'm able to update and create Membership object only using IDs of related objects. I also override to_representation(self,value) method so on get reuqests I can fill related fields with nested data. Here's my final solution:

class MembershipSerializer(serializers.ModelSerializer):

user = serializers.PrimaryKeyRelatedField(queryset = User.objects.all())
club = serializers.PrimaryKeyRelatedField(queryset = Club.objects.all())
inClubRole = serializers.PrimaryKeyRelatedField(queryset = InClubRole.objects.all())
class Meta:
    fields=(        
        'user',
        'club',
        'inClubRole',
       )        
    model = Membership

def to_representation(self, value):
    data = super().to_representation(value)  
    user_data = UserSerializer(value.user)
    club_data = ClubSerializer(value.club)
    inClubRole_data = InClubRoleSerializer(value.inClubRole)
    data['user'] = user_data.data
    data['club'] = club_data.data
    data['inClubRole'] = inClubRole_data.data
    return data
BaqBak
  • 15
  • 4