django rest framework serializer saving field value as empty strings, but no errors
from django.shortcuts import render
from rest_framework import viewsets
from rest_framework.authentication import TokenAuthentication
from .models import MyTodo
from .serializers import MyTodoSerializer
class MyTodoView(viewsets.ModelViewSet):
queryset = MyTodo.objects.all()
serializer_class = MyTodoSerializer
and my model is
from django.db import models
# Create your models here.
class MyTodo(models.Model):
# Autoincrement id
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=200, blank=True, default='')
description = models.CharField(max_length=20, blank=True, default='')
created_on = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
and my serializer is
from rest_framework import serializers
from mytodo.models import MyTodo
class MyTodoSerializer( serializers.ModelSerializer ):
title = serializers.CharField(max_length=200, default='')
description = serializers.CharField(max_length=200, default='')
created_on = serializers.DateTimeField(format="%Y-%m-%dT%H:%M:%S", required=False)
def create(self, validated_data):
return MyTodo.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.title = validated_data.get('title', instance.title)
instance.description = validated_data.get('description', instance.description)
instance.created_on = validated_data.get('created_on', instance.created_on )
instance.save()
return instance
class Meta:
model = MyTodo
fields = [ 'id','url','title','description', 'created_on' ]
Looks pretty simple, straight forward but by CURL calls are saving empty fields, but Browsable API View is working very fine. Please tell me what am I doing wrong.
Here is what I am trying to do
#!/bin/bash
b64credential=$(echo 'admin:admin' | base64)
access_token=$(curl -d "username=admin&password=admin" -X POST 'http://localhost:8000/api/token/' \
-H 'Accept:application/json' \
-H "Authorization:Basic ${b64credential}" | jq --raw-output '.access' )
echo "Access token : $access_token"
# post a todo to mytodo api
curl -vvv -L -d '{"title": "Awesome things to be done" ,"description": "Really great things stay alert"}' \
-X POST 'http://localhost:8000/mytodo/' \
-H 'Accept:application/json' \
-H "Authorization:Bearer ${access_token}"
{"id":23,"url":"http://localhost:8000/mytodo/23/","title":"","description":"","created_on":"2021-05-14T10:02:45"}
Here are couple more questions
Why I get title:"", description: "",
in the view, I have only serializer_class = MyTodoSerializer
have no information about actual request processing, how Django is correctly calling the right method MyTodoSerializer.create()
You have set ''
as default value and cURL payload is not passed to Django.
The reason is your header is wrong.
Is
-H 'Accept:application/json' \
should be
-H "Content-Type: application/json"
Try this instead.
curl -vvv -L -d '{"title": "Awesome things to be done" ,"description": "Really great things stay alert"}' -X POST 'http://localhost:8000/mytodo/' -H "Content-Type: application/json" -H "Authorization:Bearer ${access_token}"
The difference between these two headers can be found here.