Maverik Minett
Maverik Minett

Reputation: 2452

Django Rest Framework - Updating a model using model.ModelViewSet

How do I update a model using using the Django Rest Framework? I have the following model/serializer/view definitions:

foo/models.py

class FooBar (models.Model):

    title = models.CharField(max_length=255,null=False)

    def __unicode__(self):
        return self.title

foo/serializers.py

from rest_framework import serializers
from foo.models import FooBar

class FooBarSerializer(serializers.ModelSerializer):
    id = serializers.ReadOnlyField()

    class Meta:
        model = FooBar

        fields = ('id','title')
        read_only_fields = ['id']

foo/views.py

from rest_framework import viewsets

from foo.models import FooBar
from foo.serializers import FooBarSerializer

class FooViewSet(viewsets.ModelViewSet):
    queryset = FooBar.objects.order_by('id')
    serializer_class = FooBarSerializer

I am using angular in this project and I am able to create a new record by saying:

data = {'title':'New Foo Item'} $http.post(`/api/v1/foo/`, data );

How do I update a record? The following code results in a new record being created.

data = {'title':'New Foo Item', 'id':1} $http.post(`/api/v1/foo/`, data )

I have tried using $http.put and $http.patch and both result in a 405 "Method not allowed" error. I have also tried using this object id in the url with no luck:

$http.post(`/api/v1/foo/${data.id}/`, data );

Upvotes: 10

Views: 19388

Answers (2)

Maverik Minett
Maverik Minett

Reputation: 2452

The answer is to use patch. Be careful to include the trailing slash as required by Django. I had not included the trailing slash in my first attempts to patch which resulted in the "405 Method not allowed" response.

if ( data.id ) {
  # update
  $http.patch(`/api/v1/foo/${data.id}/`, data );
}
else {
  # create
  $http.post(`/api/v1/foo/`, data );
}

Upvotes: 5

Deep 3015
Deep 3015

Reputation: 10075

There are methods for creating a new FooBar instance through create method and to update them using update method in serializers.

More Details about Saving instances from DRF Docs

foo/serializers.py

from rest_framework import serializers
from foo.models import FooBar

class FooBarSerializer(serializers.ModelSerializer):
    id = serializers.ReadOnlyField()

    class Meta:
        model = FooBar

        fields = ('id','title')
        read_only_fields = ['id']
    def create(self, validated_data):
        # Create the Foo instance
        foo = FooBar.objects.create(title=validated_data['title'])
        return foo
    def update(self, instance, validated_data):
        # Update the Foo instance
        instance.title = validated_data['title']
        instance.save()
        return instance

create

data = {'title':'New Foo Item'}
$http.post('/api/v1/foo/', data );

update

data = {'title':'New Foo Item'}
$http.put('/api/v1/foo/'+id+'/', data ); //where `id` is the Foo Item ID

Upvotes: 4

Related Questions