简体   繁体   中英

AssertionError: Cannot apply DjangoModelPermissionsOrAnonReadOnly on a view that does not set `.queryset` or have a `.get_queryset()` method

I am writing a simple Django web application and I am trying implement REST API. I use django-rest-framework package. I use Python 3.x on Debian sid GNU/Linux. However, when I try access REST API through browser I'm getting error:

Traceback (most recent call last):
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/django/views/generic/base.py", line 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
    response = self.handle_exception(exc)
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/rest_framework/views.py", line 471, in dispatch
    self.initial(request, *args, **kwargs)
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/rest_framework/views.py", line 389, in initial
    self.check_permissions(request)
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/rest_framework/views.py", line 322, in check_permissions
    if not permission.has_permission(request, self):
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/rest_framework/permissions.py", line 141, in has_permission
    queryset = self._queryset(view)
  File "/home/lynx/PycharmProjects/hello_world/venv/lib/python3.6/site-packages/rest_framework/permissions.py", line 121, in _queryset
    ).format(self.__class__.__name__)
AssertionError: Cannot apply DjangoModelPermissionsOrAnonReadOnly on a view that does not set `.queryset` or have a `.get_queryset()` method.
[24/Jun/2018 14:34:41] "GET /articles/ HTTP/1.1" 500 101619

Here's my code:

news/serializers.py :

from rest_framework import serializers
from .models import Article


class ArticleSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = '__all__'

news/views.py :

from django.shortcuts import get_object_or_404, render
from django.views import generic
from rest_framework.response import Response
from rest_framework.views import APIView

from .forms import ArticleForm, CommentForm, GuestForm
from .models import Article, Guest
from .serializers import ArticleSerializer


# Create your views here.
class ArticleList(generic.ListView):
    template_name = 'news/article/list.html'
    model = Article
    context_object_name = 'articles'

    def get_queryset(self):
        return Article.objects.filter(status='published')


class ArticleDetail(generic.View):
    template_name = 'news/article/detail.html'
    comment_form = CommentForm

    def get(self, request, pk):
        article = get_object_or_404(Article,
                                    pk=pk)
        comments = article.comments
        return render(request, self.template_name,
                      {'article': article,
                       'comments': comments,
                       'comment_form': self.comment_form})

    def post(self, request, pk):
        article = get_object_or_404(Article,
                                    pk=pk)
        comments = article.comments.filter(status='published')

        form = self.comment_form(request.POST)

        if form.is_valid():
            comment = form.save(commit=False)
            comment.article = article
            comment.save()

        return render(request, self.template_name,
                      {'article': article,
                       'comments': comments,
                       'comment_form': self.comment_form})


class GuestBook(generic.View):
    template_name = 'news/guestbook/list.html'
    guest_form = GuestForm

    def get(self, request):
        guests = Guest.objects.filter(status='published')
        return render(request, self.template_name,
                      {'guests': guests,
                       'guest_form': self.guest_form})

    def post(self, request):
        guests = Guest.objects.filter(status='published')
        form = self.guest_form(request.POST)

        if form.is_valid():
            form.save()

        return render(request, self.template_name,
                      {'guests': guests,
                       'guest_form': self.guest_form})


class ArticleCreate(generic.View):
    template_name = 'news/article_form.html'
    article_form = ArticleForm

    def get(self, request):
        return render(request, self.template_name,
                      {'form': self.article_form})


class RESTArticleList(APIView):
    def get(self, request):
        articles = Article.objects.filter(status='published').all()
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)

    def post(self):
        pass

hello_world/urls.py :

"""hello_world URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path
from news import views
from rest_framework.urlpatterns import format_suffix_patterns

urlpatterns = [
    path('admin/', admin.site.urls),
    path('news/', include('news.urls')),
    path('tinymce/', include('tinymce.urls')),
    path('articles/', views.RESTArticleList.as_view()),
]


urlpatterns = format_suffix_patterns(urlpatterns)

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

I am counting for help!

From the docs :

This permission must only be applied to views that have a .queryset property set.

So try to add queryset attribute to your RESTArticleList view:

class RESTArticleList(APIView):
    queryset = Article.objects.filter(status='published')

    def get(self, request):
        articles = Article.objects.filter(status='published').all()
        serializer = ArticleSerializer(articles, many=True)
        return Response(serializer.data)

    def post(self):
        pass

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM