Search fields in custom action method

565 views Asked by At

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

There are 2 answers

2
Sorin Burghiu On

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)
0
optimus On

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