在我的Django项目中,我有一个 statement 语句应用程序,该应用程序仅存储注册用户的语句。我正在尝试用它来学习Django,有时我问自己如何仅显示当前用户的语句。因此,当我想查看语句时,我根据当前用户过滤了查询集,然后得到了此错误消息(请参见标题)。
我的views.py:
from statements.models import Statement
from statements.serializers import StatementSerializer, UserSerializer
from rest_framework import generics
from django.contrib.auth.models import User
from rest_framework import permissions
from statements.permissions import IsOwnerOrReadOnly
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
from rest_framework.views import APIView
from rest_framework.authtoken.models import Token
from rest_framework.authentication import TokenAuthentication
@api_view(['GET'])
def api_root(request, format=None):
return Response({'links':{
'users': reverse('user-list', request=request, format=format),
'statements': reverse('statement-list', request=request, format=format)
}})
class StatementList(generics.ListCreateAPIView):
#queryset = Statement.objects.all() <--- with this, everything was fine but I wanted to get only the statements of the current user
serializer_class = StatementSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
# I've overridden this method so that only the statements of the current user should be displayed (BUT this caused the error)
def get_queryset(self):
user = self.request.user
return Statement.objects.filter(owner=user)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response({'statements': serializer.data})
class StatementDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Statement.objects.all()
serializer_class = StatementSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
我的模型。py:
from django.db import models
# Create your models here.
class Statement(models.Model):
created = models.DateTimeField(auto_now_add=True)
text = models.CharField(max_length=100, blank=False)
owner = models.ForeignKey('auth.User', related_name='statements', on_delete=models.CASCADE)
class Meta:
ordering = ('created',)
我的serializers.py:
class StatementSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = Statement
fields = ('url','id', 'text', 'owner')
class UserSerializer(serializers.HyperlinkedModelSerializer):
statements = serializers.HyperlinkedRelatedField(many=True, view_name='statement-detail', read_only=True)
class Meta:
model = User
fields = ('url', 'id', 'username', 'statements')
因此,我还阅读了有关此类型错误的其他stackoverflow帖子,但它们没有帮助。
答案 0 :(得分:1)
问题出在StatementList视图中。
如果请求未经身份验证,则默认值request.user
是django.contrib.auth.models.AnonymousUser
的实例。
因此,您可以在进行Statement.objects.filter(owner=user)
查询之前检查用户是否已通过身份验证。
# views.py
class StatementList(generics.ListCreateAPIView):
#queryset = Statement.objects.all() <--- with this, everything was fine but I wanted to get only the statements of the current user
serializer_class = StatementSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
# I've overridden this method so that only the statements of the current user should be displayed (BUT this caused the error)
def get_queryset(self):
user = self.request.user
# check if the user is authenticated
if user.is_authenticated():
return Statement.objects.filter(owner=user)
return Statement.objects.none()
# END
或者您可以将permission_classes
更改为permissions.IsAuthenticated
,这将确保只有经过身份验证的用户才能访问端点。
答案 1 :(得分:0)
在settings.py中确认
调试 = 真