Context:
I have written a simple django rest framework app as BE and a react JS app as FE. The db is SQLite and it's gonna stay that way, since there are only 2 simple models and the number of users will be quite limited as well.
For the sake of the example let's assume there is only one team currently with name="First"
and id=1
.
Requirements:
- display in a table the list of players with team as a name, not its id.
- add players from form
Code:
models.py
class Player(models.Model):
first_name = models.Charfield(max_length=50)
last_name = models.Charfield(max_length=50)
team = models.ForeignKey(Team, on_delete=models.SET_NULL, blank=True, null=True)
class Team(models.Model):
name = models.Charfield(max_length=50)
def __str__(self):
return f"{self.name}"
views.py
class PlayersView(APIView):
def post(self, request):
serializer = PlayerSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
In order to meed 1st requirement I've implemented serializer like this:
serializers.py
class PlayerSerializer(serializers.ModelSerializer):
team = serializers.CharField(source="team.name", read_only=True)
class Meta:
model = Player
fields = "__all__"
That worked fine, but I wasn't able to add the players to the database when processing the request from the FE.
The body of that POST request is:
body
{
"first_name": "John",
"last_name": "Doe",
"team": 1
}
Looking on SO I found:
- Retrieving a Foreign Key value with django-rest-framework serializers
- How to serialize the foreign key field in django rest framework
- DRF serializer.save() not saving to database
I tried sending the request body as (the FE has full info on team, both name and id, that part is working fine):
body
{
"first_name": "John",
"last_name": "Doe",
"team": "First"
}
But that was a dead end.
I played with serializer and tried: serializers.py
class PlayerSerializer(serializers.ModelSerializer):
team = serializers.PrimaryKeyRelatedField(source="team.name", queryset=Team.objects.all())
def create(self, validated_data):
validated_data["team"] = validated_data["team"]["name"] # Since the Player initializer expected team to be an instance of Team and not a str/name neither an int/id
return Player(**validated_data)
def to_representation(self, instance):
r ={
"id": instance.id,
"first_name": instance.first_name,
"last_name": instance.last_namem
"team": instance.team.name if instance.team else ""
}
return r
class Meta:
model = Player
fields = "__all__"
The above does not raise any exceptions, but it doesn't save the new entry into db neither. When I logged the serializer.data
after validation the id
of the new item was None
.
I'd appreciate if somebody could either tell me where the mistake is and/or point me towards a good solution of the problem.