Reputation: 100
So, I'm new to Django and after hours of searching / trying different things I can't figure this out.
I have a form that submits my components state to the api, adds the values to the database, and then displays them in a table. Everything is getting into the database except for the "projects" field. When I look in the React Dev tools, the value I expect is in my state.
project: 3
But after I submit the form the returned value shows as null.
project: null
I'm really not sure why the value is null.
Here is my models.py
class Completed(models.Model):
completed = models.BooleanField(default=False)
url = models.CharField(max_length=100)
handle = models.CharField(max_length=30)
filename = models.CharField(max_length=100)
size = models.IntegerField()
source = models.CharField(max_length=50)
uploadId = models.CharField(max_length=50)
originalPath = models.CharField(max_length=50)
owner = models.ForeignKey(
User, related_name="completed", on_delete=models.CASCADE, null=True)
project = models.ForeignKey(
Project, related_name="projectId", on_delete=models.CASCADE, null=True)
uploadDate = models.DateTimeField(auto_now_add=True)
Here is the Project model
class Project(models.Model):
projectCode = models.CharField(max_length=10)
projectName = models.CharField(max_length=100)
user = models.ForeignKey(
User, related_name="projects", on_delete=models.CASCADE, null=True)
editor = models.ForeignKey(
User, on_delete=models.CASCADE, null=True)
creationDate = models.DateTimeField(auto_now_add=True)
completedDate = models.DateTimeField(null=True, blank=True)
dueDate = models.DateTimeField(null=True, blank=True)
def __str__(self):
return f"{self.projectName}"
Here are the serializers
# Project Serializer
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = [
'id',
'projectCode',
'projectName',
'user'
]
depth = 1
# Completed Serializer
class CompletedSerializer(serializers.ModelSerializer):
# project = ProjectSerializer()
class Meta:
model = Completed
fields = [
'completed',
'url',
'handle',
'filename',
'size',
'source',
'uploadId',
'originalPath',
'owner',
'project',
'uploadDate'
]
depth = 1
I tried adding the ProjectSerializer into the CompletedSerializer but it gave me a 400 bad-request error.
And here is the viewset
class CompletedViewSet(viewsets.ModelViewSet):
permission_classes = [
permissions.IsAuthenticated
]
serializer_class = CompletedSerializer
def get_queryset(self):
queryset = self.request.user.completed.all().filter(completed=True)
return queryset
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
Can anyone tell me what I'm doing wrong here?
Upvotes: 0
Views: 171
Reputation: 899
You're using depth=1
on your serializers. That means you'll have nested serializer for your ForeignKey
. By default, nested serializers are read-only. If you want a writable nested serializer, you have to uncomment your # project = ProjectSerializer()
on CompletedSerializer
and pass all the data for the creation of a project instance. I don't think this is what you want. If I've understood well, you only want to reference an existing project. So, the best way to accomplish that, in my opinion, is removing the depth
on your CompletedSerializer
. If you need the project when you list or retrieve a Completed instance, go with a different serializer based on the request action. Here more details about writable-nested serializers https://www.django-rest-framework.org/community/3.0-announcement/#writable-nested-serialization.
For using different serializers, this is a reference. Add this code in your ViewSet:
def get_serializer_class(self):
if self.action == 'list' or self.action == 'retrieve':
return CompletedNestedSerializer
return CompletedSerializer
Upvotes: 1