英文:
Making a that enables 'GET' without token but not posts without tokens
问题
我最近开始参与Django后端开发,所以我仍然在一些功能上有困难。这次,我遇到了一个相当具有挑战性的问题,我在网上找不到任何有用的答案。我正在创建一个支持'GET'和'POST'请求的视图。我面临的问题是,虽然我需要一个Bearer令牌来执行'POST'请求,但我不希望对'GET'请求要求令牌。最初,我考虑为'GET'请求创建一个单独的视图,但那似乎是多余的。然后,我在Django Rest Framework文档中找到了'IsAuthenticatedOrReadOnly'权限类。我认为这会解决我的问题,但即使在实施了这个验证后,'GET'端点仍然要求令牌。请问有人能提供一些见解吗?
这是我的视图:
from rest_framework.views import Request, Response, status, APIView
from .serializers import MovieSerializer
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from movies.models import Movie
class MovieView(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticatedOrReadOnly]
def post(self, request: Request) -> Response:
serializer = MovieSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(user=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
def get(self, request: Request) -> Response:
movies = Movie.objects.all()
serializer = MovieSerializer(movies, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
...以防需要的话...这是我的模型:
from django.db import models
class MovieRating(models.TextChoices):
G = 'G'
PG = 'PG'
PG13 = 'PG-13'
R = 'R'
NC17 = 'NC-17'
class Movie(models.Model):
title = models.CharField(max_length=127)
duration = models.CharField(max_length=127, blank=True, null=True, default=None)
rating = models.CharField(max_length=20, choices=MovieRating.choices, default=MovieRating.G)
synopsis = models.TextField(blank=True, null=True, default=None)
user = models.ForeignKey(
"users.User",
on_delete=models.CASCADE,
related_name="movies",
default=None
)
希望这可以帮助你解决你的问题。
英文:
I recently started working with Django backend development, so I'm still struggling with some features. This time, I've encountered a problem that has been quite challenging, and I couldn't find any helpful answers on the web. I'm creating a view that supports both 'GET' and 'POST' requests. The issue I'm facing is that while I need a Bearer token for the 'POST' request, I don't want to require a token for the 'GET' request. Initially, I considered creating a separate view just for the 'GET' request, but that seemed redundant. Then, I came across the 'IsAuthenticatedOrReadOnly' permission class in the Django Rest Framework documentation. I thought this would solve my problem, but even after implementing this verification, the 'GET' endpoint still asks for a token. Could someone please provide me with some insights?
Here's my view:
from rest_framework.views import Request, Response, status, APIView
from .serializers import MovieSerializer
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from movies.models import Movie
class MovieView(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticatedOrReadOnly]
def post(self, request: Request) -> Response:
serializer = MovieSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(user = request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
def get(self, request: Request) -> Response:
movies = Movie.objects.all()
serializer = MovieSerializer(movies, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
...and in case you need... here's my model:
from django.db import models
# Create your models here.
class MovieRating(models.TextChoices):
G = 'G'
PG = 'PG'
PG13 = 'PG-13'
R = 'R'
NC17 = 'NC-17'
class Movie(models.Model):
title = models.CharField(max_length=127)
duration = models.CharField(max_length=127, blank=True, null=True, default=None)
rating = models.CharField(max_length=20, choices=MovieRating.choices, default=MovieRating.G)
synopsis = models.TextField(blank=True, null=True, default=None)
user = models.ForeignKey(
"users.User",
on_delete=models.CASCADE,
related_name="movies",
default=None
)
答案1
得分: 1
你可以根据所发出的请求覆盖get_permissions
类。下面的示例适用于ModelViewSet。
def get_permissions(self):
if self.action in ['list', 'retrieve']:
# 获取请求
return (permissions.AllowAny(),)
else:
# 其他请求
return (permissions.IsAuthenticated(),)
英文:
You can override the get_permissions
class based on the request made. The example below works with ModelViewSet.
def get_permissions(self):
if self.action in ['list', 'retrieve']:
# Get requests
return (permissions.AllowAny(),)
else:
# Any other request
return (permissions.IsAuthenticated(),)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论