Django not saving data with post
Question:
I have this view:
class TaskApiView(APIView):
def post(self, request):
serializer = TaskSerializer(data=request.data)
print(request.data)
if serializer.is_valid():
print("valid", serializer.data)
serializer.save()
return Response(status=status.HTTP_201_CREATED)
else:
print(serializer.errors)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
request body:
{
"content": "asd"
}
log:
{'content': 'asd'}
valid {'id': 30}
[21/Oct/2023 11:33:19] "POST /api/task/create HTTP/1.1" 201 0
But when I try to get all tasks with this view
class TaskListAPIView(generics.ListAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer
I get just the id:
[
{
"id": 25
}
]
Serializer:
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = "__all__"
Model
id: models.UUIDField(unique=True, auto_created=True)
content: models.CharField(default="")
creationDate: models.DateField(auto_now_add=True)
author: models.ForeignKey(User, on_delete=models.CASCADE)
status: models.CharField(
choices=StatusEnum,
max_length=5,
default=StatusEnum.TODO,
)
def __str__(self):
return self.id + self.content
settings.py:
REST_FRAMEWORK = {
"DEFAULT_PARSER_CLASSES": [
"rest_framework.parsers.JSONParser",
]
}
I want to create a task with content
Answers:
Well that’s because your model only has an id
field. Indeed, you define fields as attributes, not as annotations, so:
class Task(models.Model):
id = models.UUIDField(unique=True, auto_created=True)
content = models.CharField(default='')
creationDate = models.DateField(auto_now_add=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(
choices=StatusEnum, max_length=5, default=StatusEnum.TODO
)
def __str__(self):
return f'{self.id} {self.content}'
You will need to make a migration and migrate to migrate it properly. Likely injecting defaults for already existing models.
With the given data you provide, the serializer will however reject the data: you don’t specify a value for the author
.
I have this view:
class TaskApiView(APIView):
def post(self, request):
serializer = TaskSerializer(data=request.data)
print(request.data)
if serializer.is_valid():
print("valid", serializer.data)
serializer.save()
return Response(status=status.HTTP_201_CREATED)
else:
print(serializer.errors)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
request body:
{
"content": "asd"
}
log:
{'content': 'asd'}
valid {'id': 30}
[21/Oct/2023 11:33:19] "POST /api/task/create HTTP/1.1" 201 0
But when I try to get all tasks with this view
class TaskListAPIView(generics.ListAPIView):
queryset = Task.objects.all()
serializer_class = TaskSerializer
I get just the id:
[
{
"id": 25
}
]
Serializer:
class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = Task
fields = "__all__"
Model
id: models.UUIDField(unique=True, auto_created=True)
content: models.CharField(default="")
creationDate: models.DateField(auto_now_add=True)
author: models.ForeignKey(User, on_delete=models.CASCADE)
status: models.CharField(
choices=StatusEnum,
max_length=5,
default=StatusEnum.TODO,
)
def __str__(self):
return self.id + self.content
settings.py:
REST_FRAMEWORK = {
"DEFAULT_PARSER_CLASSES": [
"rest_framework.parsers.JSONParser",
]
}
I want to create a task with content
Well that’s because your model only has an id
field. Indeed, you define fields as attributes, not as annotations, so:
class Task(models.Model):
id = models.UUIDField(unique=True, auto_created=True)
content = models.CharField(default='')
creationDate = models.DateField(auto_now_add=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(
choices=StatusEnum, max_length=5, default=StatusEnum.TODO
)
def __str__(self):
return f'{self.id} {self.content}'
You will need to make a migration and migrate to migrate it properly. Likely injecting defaults for already existing models.
With the given data you provide, the serializer will however reject the data: you don’t specify a value for the author
.