django-rest-framework "AttributeError: 'function' object has no attribute 'get_extra_actions' "

Viewed 354

django==3.2.4 djangorestframework==3.12.4

blog/serializer.py

from rest_framework import serializers
from .models import Blog

class BlogSerializer(serializers.ModelSerializer):
    class Meta:
        model = Blog
        fields = '__all__'

blog/views.py

from rest_framework import generics
from .models import Blog
from .serializers import BlogSerializer

class BlogListCreateView(generics.ListCreateAPIView):
    queryset = Blog.objects.all()
    serializer_class = BlogSerializer

class BlogRetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Blog.objects.all()
    serializer_class = BlogSerializer

blog/urls.py

router = DefaultRouter()
router.register(r'blogs', BlogListCreateView.as_view(), basename="blogs")
router.register(r'action/<int:pk>', BlogRetrieveUpdateDestroyView.as_view(), basename="action")

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

when i use router it shows AttributeError: 'function' object has no attribute 'get_extra_actions' but when i use normal django urls path it run successfully

blog/urls.py

urlpatterns = [
    path('blog/', BlogListCreateView.as_view(), name="blog"),
    path('blog/<int:pk>', BlogRetrieveUpdateDestroyView.as_view(), name="action"),
]
2 Answers

From documentation:

Because we're using ViewSet classes rather than View classes, we actually don't need to design the URL conf ourselves. The conventions for wiring up resources into views and urls can be handled automatically, using a Router class.

So you don't need the path to be 'action/<int:pk>'. 'action' will suffice.

Routers are used for Viewsets, not for generics views from Django. For Example:

from rest_framework import routers

router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
urlpatterns = router.urls

Here's how to do it using generics.

Related