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

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

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(),)

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:

确定