Django REST Framework update record mixin

Viewed 399

I'm using Django 3.2 and the last version of djangorestframework.

I need to be able to update the values of JobStatus record already crated before.

As example I have

 {
    "id": 1,
    "status_timestamp": "2022-04-07T10:51:42Z",
    "status_activity": "Sync DDT",
    "status_status": "running",
    "launcher": 1
  }

and I need to obtain this (in the DB) via API

 {
    "id": 1,
    "status_timestamp": "2022-04-07T11:51:42Z",
    "status_activity": "Sync DDT",
    "status_status": "completed",
    "launcher": 1
  }

Can someone help me out?

PS I need to mantain the Token authentication method


MODELS

class JobStatus(models.Model):
    status_timestamp = models.DateTimeField()
    status_activity = models.CharField(max_length=200)
    status_status = models.CharField(max_length=200)
    launcher = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.RESTRICT)
    class Meta:
        verbose_name = "Status"
        verbose_name_plural = "Status list"

    def __str__(self):
        return str(self.status_timestamp) + " " + self.status_activity

URLS

from django.urls import path, include
from apps.api_c import views
from rest_framework.routers import DefaultRouter
from rest_framework.urlpatterns import format_suffix_patterns


router = DefaultRouter()
router.register('alert', views.AlertViewSet)
router.register('jstatus', views.UpdateStatus)

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

VIEWS

class UpdateStatus(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin):
    """update status"""
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)
    serializer_class = StatusSerializer
    #queryset = JobStatus.objects.all()
#TEST1
    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)
#TEST2
    def perform_update(self, serializer):
        serializer_class.update()
1 Answers

You could do this:

urls.py

from apps.api_c import views
from rest_framework.routers import DefaultRouter
from rest_framework.urlpatterns import format_suffix_patterns


router = DefaultRouter()
router.register('alert', views.AlertViewSet,basename="alert")
router.register('jstatus', views.UpdateStatus, basename="updatestatus")

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

views.py


    class UpdateStatus(viewsets.GenericViewSet, 
                       mixins.ListModelMixin, 
                       mixins.RetrieveModelMixin, 
                       mixins.UpdateModelMixin):
        """update status"""
        authentication_classes = (TokenAuthentication,)
        permission_classes = (IsAuthenticated,)
        queryset = JobStatus.objects.all()
        serializer_class = StatusSerializer

        def get_serializer_class(self):

           if self.action == 'update' or self.action == 'put' or self.action == 'patch':
              return StatusUpdateSerializer

       

           return StatusSerializer



Then your StatusUpdateSerializer would look like:

class StatusUpdateSerializer(serializers.ModelSerializer):
    

    class Meta:

        model = models.JobStatus
        fields =("id","status_timestamp","status_activity","status_status",
        "launcher")
        read_only_fields = ("id","status_timestamp","status_activity",
        "launcher")

This should work.

So basically you would need to switch your serializers based on the request method the user is making thus: def get_serializer_class(self) method.

In StatusUpdateSerializer all the fields are listed.But in the readonly field only list fields that you do not want the user to be able to update or edit.

Related