Search code examples
pythondjangodjango-modelsdjango-rest-frameworkdjango-views

How to assign the user making the request to a foreign key field in Django models


I'm currently working on a web app similar to discord. I'm trying to set the user who is sending the request to create the server as the owner of the server so that the only thing he wants to enter is details like - name , icon and description. This is my model for server:

class Server(models.Model):
    name = models.CharField(max_length=30)
    owner = models.ForeignKey(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="server_owner")
    creation_date = models.DateTimeField(auto_now_add=True)
    description = models.CharField(max_length=250, null=True, blank=True)
    member = models.ManyToManyField(
        settings.AUTH_USER_MODEL, related_name="servers", through='ServerMember')
    icon = models.FileField(
        upload_to=server_icon_upload_path, null=True, blank=True)

    def __str__(self):
        return self.name

    def save(self, *args, **kwargs):
        is_new_server = self._state.adding
        if is_new_server:
            super().save(*args, **kwargs)

            try:
                member_role = Role.objects.create(
                    name="member",
                    server=self
                )
                server_member = ServerMember.objects.create(
                    user=self.owner, server=self)
                server_member.role.add(member_role)
            except Exception as e:
                print(f"Error creating 'member' role: {e}")

        if self.id:
            existing = get_object_or_404(Server, id=self.id)
            if existing.icon and existing.icon != self.icon:
                # Delete the old icon
                existing.icon.delete(save=False)

        super().save(*args, **kwargs)

serializer:

class ServerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Server
        fields = '__all__'

I've tried to override the perform_create function but it didn't work:

class ServerCreateView(generics.CreateAPIView):
    queryset = Server.objects.all()
    serializer_class = ServerSerializer
    permission_classes = [IsAuthenticated] 

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

This was the error I was getting when I was testing the apis : response

{
    "owner": [
        "This field is required."
    ]
}

Solution

  • perform_create is never called because the validation fails before that.

    Either remove the owner field from validation (for example by excluding the field from the serializer), or supply a value for that field in the serializer's initial data so that validation succeeds.