Django Rest Framework Update or Create if not exists

5.9k Views Asked by At

I want to use the perform an update or create in django-rest-framework, by passing or not the id field. I've got this model

class Etiqueta(models.Model):
    name_tag = models.CharField(max_length=200, blank=False, null=False)
    description_tag = models.TextField(max_length=500, blank=False, null=False)

    def __unicode__(self):
        return self.name_tag

And in django-rest-framework I've got this serializer

from myapp.modulos.estado_1.models import Etiqueta
from rest_framework import serializers, viewsets

# Serializers define the API representation.
class TagSerializer(serializers.ModelSerializer):
    class Meta:
        model = Etiqueta
        fields = (
            'id',
            'name_tag',
            'description_tag'
        )

# ViewSets define the view behavior.
class TagViewSet(viewsets.ModelViewSet):
    queryset = Etiqueta.objects.all()
    serializer_class = TagSerializer

Normally when I create an object, I perform a POST to the URL without the /:id, but if I've got an object with a local id, I want him to be created in the REST with the same id (remote id), django overwrite my local id and creates a new one. Does anybody know how achieve this? Also it is important to mention that I'm working with google-app-engine, google-cloud-datastore and django-dbindexer.

3

There are 3 best solutions below

8
On

This code should work for your case -

class TagViewSet(viewsets.ModelViewSet):
      queryset = Etiqueta.objects.all()
      serializer_class = TagSerializer

      def get_object(self):
          if self.request.method == 'PUT':
              obj, created = Etiquetta.objects.get_or_create(pk=self.kwargs.get('pk'))
              return obj
          else:
              return super(TagViewSet, self).get_object()
0
On

You should have a look at how Django REST framework does currently and adapts your create method to update whenever you have an id field.

The original ViewSet.create is here and the ViewSet.update is here.

Please note that you will probably end up with two different serializers for /tag/ and /tag/:id since the later should not allow the id field to be writable while the former should.

0
On

I've write a drf views mixin for updating an object by id, if no corresponding object, just create it then update.