0
0

自作デコレータで特定のビューに対してCORSを有効にする

Last updated at Posted at 2023-12-28

行った手順

django-cors-headersのデコレータを用いて実装します。

1: decorators.py ファイルの作成

mydjangoapp ディレクトリに decorators.py ファイルを新しく作成。

backend/mydjangoapp/decorators.py
from rest_framework.response import Response
from rest_framework import status

def api_check_post_method(view_func):
    def _wrapped_view(request, *args, **kwargs):
        if request.method != 'POST':
            return Response({'status': 'method not allowed'}, status=status.HTTP_405_METHOD_NOT_ALLOWED)
        return view_func(request, *args, **kwargs)
    return _wrapped_view

2: デコレーターのインポート

views.py に上記で作成したデコレーターをインポートする。
以下を追加↓

backend/mydjangoapp/views.py
from .decorators import api_check_post_method

3: デコレーターの適用

POST メソッドのチェックを行う関数の上に @api_check_post_method デコレーターを適用します。

backend/mydjangoapp/views.py
from django.contrib.auth import authenticate, logout
from rest_framework import status, viewsets
from rest_framework.response import Response
from rest_framework.decorators import api_view
from .serializers import CustomUserSerializer, CharacterSerializer
from .models import Character
from django.contrib.auth import get_user_model
from .decorators import api_check_post_method  # 新しいデコレータをインポート

@api_view(['POST'])
@api_check_post_method  # デコレータを適用
def login_view(request):
    username = request.data.get('username')
    password = request.data.get('password')
    user = authenticate(request, username=username, password=password)
    if user is not None:
        return Response({'status': 'success', 'username': username}, status=status.HTTP_200_OK)
    else:
        return Response({'status': 'fail'}, status=status.HTTP_401_UNAUTHORIZED)

@api_view(['POST'])
@api_check_post_method  # デコレータを適用
def logout_view(request):
    logout(request)
    return Response({"message": "Logged out successfully"}, status=status.HTTP_200_OK)

@api_view(['POST'])
@api_check_post_method  # デコレータを適用
def signup_view(request):
    username = request.data.get('username')
    password = request.data.get('password')
    email = request.data.get('email')
    if username is None or password is None:
        return Response({"message": "Username and password required"}, status=status.HTTP_400_BAD_REQUEST)
    user_model = get_user_model()
    user = user_model(username=username, email=email)
    user.set_password(password)
    user.save()
    return Response({"message": "User created successfully"}, status=status.HTTP_201_CREATED)

class CustomUserViewSet(viewsets.ModelViewSet):
    queryset = get_user_model().objects.all()
    serializer_class = CustomUserSerializer

class CharacterViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Character.objects.all()
    serializer_class = CharacterSerializer

@api_view(['POST'])
@api_check_post_method  # デコレータを適用
def ask_character_view(request, character_id):
    return Response({"answer": "Answer will be implemented later"}, status=status.HTTP_200_OK)

@api_view(['GET'])
def character_detail_view(request, character_id):
    try:
        character = Character.objects.get(id=character_id)
        serializer = CharacterSerializer(character)
        return Response(serializer.data, status=status.HTTP_200_OK)
    except Character.DoesNotExist:
        return Response({"message": "Character not found"}, status=status.HTTP_404_NOT_FOUND)

この関数内で、リクエストのメソッドが POST でなければ、405 メソッド不許可のレスポンスが返され、それ以外の場合は本来のビュー関数が実行されます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0