Search fields in custom action method

Viewed 136

now i'm studying DRF and have to do project with photo albums. One of my tasks is to create custom @action "patch" method, using model field "title", but i can't understand how to add fields for search in custom methods. We can see them in base methods, like "get", "patch" and "put", but i can't find any info about how to add them to custom actions. If anyone knows how to do it, please, tell me.

My model:

class PhotoAlbum(models.Model):
    title = models.CharField(verbose_name='Название альбома', max_length=50, null=True)
    created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name='Автор')
    created_at = models.DateTimeField(verbose_name='Дата создания', editable=False,
                                      default=datetime.datetime.today())

    class Meta:
        verbose_name = 'Фотоальбом'
        verbose_name_plural = 'Фотоальбомы'

    def __str__(self):
        return f'{self.title} Автор: {self.created_by} Дата: {self.created_at}'

My view:

def photo_album_view(request):
    photo_albums = PhotoAlbum.objects.all()
    context = {
        'photo_albums': photo_albums,
    }

    return render(request, 'photo_album.html', context=context)

My viewset:

class AlbumFilter(django_filters.FilterSet):
    title = django_filters.Filter(field_name='title')


class PhotoAlbumViewSet(viewsets.ModelViewSet):
    queryset = PhotoAlbum.objects.all()
    filterset_class = AlbumFilter
    serializer_class = PhotoAlbumSerializer
    pagination_class = ResultPagination
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    search_fields = ['title', ]
    ordering_fields = ['created_at', ]
2 Answers

To answer the above say you have a viewset class

// all imports
class AbcApi(viewsets.ModelViewset):
   serializer_class = random
   permission_classses = [IsAuthenticated]
   search_fields = ["a_field", "b_field"]
   filter_backends = [....]
   
   #custom action
   @action(detail=False)
   def custom_action(self, *args, **kwargs):
       """ to answer your question """
       qset_ = **self.filter_queryset**(self.queryset()) 
       #the filter bold automatically involves the class filters in the custom method

the answer is to use self.filter_queryset(..pass the get_queryset()) here as seen

If you are using ModelViewSet, I believe you are looking for one of these custom methods:

def update(self, request, pk=None):
    pass

def partial_update(self, request, pk=None):
    pass

These functions allow you to add custom functionalities to your update method. Reference

Brief example:

def partial_update(self, request, pk=None):
            serializer = UserPostSerializer(user, data=request.data, partial=True)
            if serializer.is_valid():
                try:
                    serializer.save()
                except ValueError:
                    return Response({"detail": "Serializer not valid."}, status=400)
                return Response({"detail": "User updated."})
            else:
                return Response(serializer.errors)
Related