How to create or update a model with Django REST Framework?

Question:

I would like to create or update a model Account by specifying the fields id and params with the REST Framework. To begin with, I try to create the model but I’m constantly getting 400 or 500 error code. What am’I missing?

client

data = dict(id=18, params=dict(foo='bar'))
res = requests.post('http://container-django-1:8002/api/account/',
    data=data,
    headers={'Authorization': 'Bearer {0}'.format(instance.bookkeeper.jwt_token)}
)

server

models.py

class Account(TimestampedModel):
    active = models.BooleanField(null=True, blank=True, default=False)
    params = models.JSONField(default=dict, blank=True)

views.py

class AccountViewSet(viewsets.ModelViewSet):
    serializer_class = AccountSerializer
    queryset = Account.objects.all()
    http_method_names = ['post']

serializer.py

class AccountSerializer(serializers.ModelSerializer):

    class Meta:
        model = Account
        fields = ('id', 'params',)

    def create(self, validated_data):
        return Account.objects.create(id=validated_data['id'],
                                      params=validated_data['params'])

urls.py

router = routers.DefaultRouter()
router.register("account", AccountViewSet, basename="accounts-list")

urlpatterns = [
    path('', include(router.urls)),
]

Output

container-django-1  | 2022-09-03T18:14:22.785593661Z Starting development server at http://0.0.0.0:8002/
container-django-1  | 2022-09-03T18:14:22.785604944Z Quit the server with CONTROL-C.
container-django-1  | 2022-09-03T18:17:09.252092179Z Bad Request: /api/account/
container-django-1  | 2022-09-03T18:17:09.253001155Z Bad Request: /api/account/
container-django-1  | 2022-09-03T18:17:09.261351802Z [03/Sep/2022 18:17:09] "POST /api/account/ HTTP/1.1" 400 40
Asked By: Florent

||

Answers:

params should be json after deserialization. In your sample, params is deserialized as a dictionary. Convert params to json in your request by calling json.dumps(), so you will receive a json after deserialization.

import json 

data = dict(id=18, params=json.dumps(dict(foo='bar')))
res = requests.post('http://container-django-1:8002/api/account/',
    data=data,
    headers={'Authorization': 'Bearer {0}'.format(instance.bookkeeper.jwt_token)}
)

Answered By: Pouya Esmaeili