Django Rest framework how to create Family and assign members to that family while assigning roles to each member

Viewed 197

I have my parishioner model like below (Only pasting relevant CODE)

class Parishioner(models.Model):
    family = models.ForeignKey(Family, null=True, on_delete=models.PROTECT, related_name='members')
    role = models.ForeignKey(FamilyRole, null=True, blank=True, on_delete=models.PROTECT, related_name='role')

Parishioner can have one Family and One role in that family

So I'm trying to achieve this in my Family Serializer.

class FamilySerializer(serializers.ModelSerializer):
    members = serializers.PrimaryKeyRelatedField(
        many=True,
        queryset=Parishioner.objects.all(),
        allow_null=True,
        required=False
    )

    class Meta:
        model = Family
        fields = ('id', 'name', 'address', 'monthly_contribution', 'members', 'enabled')
        read_only_fields = ('id',)
        depth = 1

As you can see above I can clearly assign members to that Family.

But I want to assign roles to Each family member as well. How can I do that in Django ?

Examples for FamilyRole: Father, Mother, son, daughter

My front end will be similar to this in my Create Family page (and I expect to send only one request to server to achieve this by using api/family/ endpoint)

enter image description here

Simply I want to,

Create a Family,

Assign Members(Parishioners) to that Family,

Assign Role to each of those Member(Parishioner),

Through api/family/ endpoint.

What is the best way to achieve above ?

1 Answers

You can do all of that in the serializer by using the function create (it would be the same with update, but you are talking here of creation).

class FamilySerializer(serializers.ModelSerializer):
    # No need to define members here as it is the related name
    # and that it will popped out
    class Meta:
        model = Family
        fields = ('id', 'name', 'address', 'monthly_contribution', 'members', 'enabled')
        read_only_fields = ('id',)

    def create(self, validated_data):
        members = None
        if 'members' in validated_data.keys():
            members = validated_data.pop('members')

        # Create the family
        family = Family.objects.create(**validated_data)

        # Deal with members data
        if members is not None:
            for member_data in members:
                role_id = member_data.get('role', None)
                if role_id is not None:
                    role = Role.objects.get(id=role_id)
                    Parishioner.objects.create(
                        family=family,
                        role=role
                    )
        return family

The family is created and returned, and the members are created too with the correspondent role. On the front, it would like that :

        axios.post('api/family/', {
            family_name: 'Smith',
            members: [
                {
                    role: '3' # Father id for example
                },
                {
                    role: '2', # Mother id
                }
            ]
        })

You can change of course the role and use the name if you want. Just be careful to be coherent between the field to identify the role in front and back Role.objects.get(field=value)

Related