I used to follow this pattern in Django Rest Framework (DRF) 2:
class Foo(models.Model):
user = models.ForeignKey(User)
class FooSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Foo
fields = ('url')
class FooViewset(viewsets.ModelViewSet):
def get_queryset(self):
return Foo.objects.filter(user=self.request.user)
serializer = FooSerializer
model = Foo # <-- the way a ModelViewSet is told what the object is in DRF 2
[ in urls.py]
from rest_framework import routers
router = routers.DefaultRouter()
router.register('Foo', views.FooViewSet)
In DRF 3, I now get:
AssertionError at /
`base_name` argument not specified, and could not automatically
determine the name from the viewset, as it does not have a
`.queryset` attribute.
How is get_queryset overridden for an instance of rest_framework.viewsets.ModelViewSet?
I think you shouldn't need to pass detail=True when you call MyViewSet , so you can call it MyViewSet(). my_action(request,pk=request. data['my_id']) (or make an instance of your class). Have you tried defined your action like def my_action(self, request, *args, **kwargs) and in your kwargs receive the pk variable?
APIView allow us to define functions that match standard HTTP methods like GET, POST, PUT, PATCH, etc. Viewsets allow us to define functions that match to common API object actions like : LIST, CREATE, RETRIEVE, UPDATE, etc.
A ViewSet class is simply a type of class-based View, that does not provide any method handlers such as . get() or . post() , and instead provides actions such as . list() and . create() .
The root QuerySet provided by the Manager describes all objects in the database table. Usually, though, you'll need to select only a subset of the complete set of objects. The default behavior of REST framework's generic list views is to return the entire queryset for a model manager.
Figured this one out. The model field of the rest_framework.viewsets.ModelViewSet does seem to be AWOL in DRF3. Now, if you override get_queryset you need to specify a third parameter to routers.DefaultRouter().register which is the basename parameter. Then, the function won't go off and try to find it on the non-existent queryset field of the ModelViewSet.
e.g.
router = routers.DefaultRouter()
[...]
router.register('/rest/FooBar'/, views.FooBarViewSet, 'foobar-detail')
#^^^^^^^^^^^^^^^
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With