Making a that enables 'GET' without token but not posts without tokens

huangapple go评论101阅读模式
英文:

Making a that enables 'GET' without token but not posts without tokens

问题

我最近开始参与Django后端开发,所以我仍然在一些功能上有困难。这次,我遇到了一个相当具有挑战性的问题,我在网上找不到任何有用的答案。我正在创建一个支持'GET'和'POST'请求的视图。我面临的问题是,虽然我需要一个Bearer令牌来执行'POST'请求,但我不希望对'GET'请求要求令牌。最初,我考虑为'GET'请求创建一个单独的视图,但那似乎是多余的。然后,我在Django Rest Framework文档中找到了'IsAuthenticatedOrReadOnly'权限类。我认为这会解决我的问题,但即使在实施了这个验证后,'GET'端点仍然要求令牌。请问有人能提供一些见解吗?

这是我的视图:

  1. from rest_framework.views import Request, Response, status, APIView
  2. from .serializers import MovieSerializer
  3. from rest_framework_simplejwt.authentication import JWTAuthentication
  4. from rest_framework.permissions import IsAuthenticatedOrReadOnly
  5. from movies.models import Movie
  6. class MovieView(APIView):
  7. authentication_classes = [JWTAuthentication]
  8. permission_classes = [IsAuthenticatedOrReadOnly]
  9. def post(self, request: Request) -> Response:
  10. serializer = MovieSerializer(data=request.data)
  11. serializer.is_valid(raise_exception=True)
  12. serializer.save(user=request.user)
  13. return Response(serializer.data, status=status.HTTP_201_CREATED)
  14. def get(self, request: Request) -> Response:
  15. movies = Movie.objects.all()
  16. serializer = MovieSerializer(movies, many=True)
  17. return Response(serializer.data, status=status.HTTP_200_OK)

...以防需要的话...这是我的模型:

  1. from django.db import models
  2. class MovieRating(models.TextChoices):
  3. G = 'G'
  4. PG = 'PG'
  5. PG13 = 'PG-13'
  6. R = 'R'
  7. NC17 = 'NC-17'
  8. class Movie(models.Model):
  9. title = models.CharField(max_length=127)
  10. duration = models.CharField(max_length=127, blank=True, null=True, default=None)
  11. rating = models.CharField(max_length=20, choices=MovieRating.choices, default=MovieRating.G)
  12. synopsis = models.TextField(blank=True, null=True, default=None)
  13. user = models.ForeignKey(
  14. "users.User",
  15. on_delete=models.CASCADE,
  16. related_name="movies",
  17. default=None
  18. )

希望这可以帮助你解决你的问题。

英文:

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:

  1. from rest_framework.views import Request, Response, status, APIView
  2. from .serializers import MovieSerializer
  3. from rest_framework_simplejwt.authentication import JWTAuthentication
  4. from rest_framework.permissions import IsAuthenticatedOrReadOnly
  5. from movies.models import Movie
  6. class MovieView(APIView):
  7. authentication_classes = [JWTAuthentication]
  8. permission_classes = [IsAuthenticatedOrReadOnly]
  9. def post(self, request: Request) -> Response:
  10. serializer = MovieSerializer(data=request.data)
  11. serializer.is_valid(raise_exception=True)
  12. serializer.save(user = request.user)
  13. return Response(serializer.data, status=status.HTTP_201_CREATED)
  14. def get(self, request: Request) -> Response:
  15. movies = Movie.objects.all()
  16. serializer = MovieSerializer(movies, many=True)
  17. return Response(serializer.data, status=status.HTTP_200_OK)

...and in case you need... here's my model:

  1. from django.db import models
  2. # Create your models here.
  3. class MovieRating(models.TextChoices):
  4. G = 'G'
  5. PG = 'PG'
  6. PG13 = 'PG-13'
  7. R = 'R'
  8. NC17 = 'NC-17'
  9. class Movie(models.Model):
  10. title = models.CharField(max_length=127)
  11. duration = models.CharField(max_length=127, blank=True, null=True, default=None)
  12. rating = models.CharField(max_length=20, choices=MovieRating.choices, default=MovieRating.G)
  13. synopsis = models.TextField(blank=True, null=True, default=None)
  14. user = models.ForeignKey(
  15. "users.User",
  16. on_delete=models.CASCADE,
  17. related_name="movies",
  18. default=None
  19. )

答案1

得分: 1

你可以根据所发出的请求覆盖get_permissions类。下面的示例适用于ModelViewSet

  1. def get_permissions(self):
  2. if self.action in ['list', 'retrieve']:
  3. # 获取请求
  4. return (permissions.AllowAny(),)
  5. else:
  6. # 其他请求
  7. return (permissions.IsAuthenticated(),)
英文:

You can override the get_permissions class based on the request made. The example below works with ModelViewSet.

  1. def get_permissions(self):
  2. if self.action in ['list', 'retrieve']:
  3. # Get requests
  4. return (permissions.AllowAny(),)
  5. else:
  6. # Any other request
  7. return (permissions.IsAuthenticated(),)

huangapple
  • 本文由 发表于 2023年6月19日 15:56:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76504659.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定