django "detail": "Method \"GET\" not allowed." (one to many relationship)

Viewed 130

models.py

from django.db import models

class User(models.Model):
    username = models.CharField(max_length=64)

class Games(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    game = models.CharField(max_length=128)

serializers.py

from rest_framework import serializers
from . import models

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.User
        fields = '__all__'

class GameSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Games
        fields = '__all__'

views.py

from django.shortcuts import render
from . import models
from . import serializers
from rest_framework import generics, status
from rest_framework.views import APIView
from rest_framework.response import Response

class UserView(generics.ListCreateAPIView):
    queryset = models.User.objects.all()
    serializer_class = serializers.UserSerializer

class CreateUser(APIView): # this works just fine
    def post(self, request):
        serializer = serializers.UserSerializer(data= request.data)
        if serializer.is_valid():
            username = serializer.data.get('username')

            queryset = models.User.objects.filter(username)
            if queryset.exists():
                user = queryset[0]
                user.username = username

                user.save(update_fields=['username'])
            else:
                user = models.User.objects.create(username=username)
                user.save()
                return Response(serializers.UserSerializer(user).data, status=status.HTTP_200_OK)
            return Response({'BAD REQUEST': 'INVALID DATA'}, status=status.HTTP_400_BAD_REQUEST)

class CreateGame(APIView): # this is causing problems
    def post(self, request):
        serializer = serializers.GameSerializer(data= request.data)
        if serializer.is_valid():
            game = serializer.data.get('game')
            user = serializer.data.get('user')
            
            game = models.Games.objects.create(user=user, game=game)
            game.save()
            return Response(serializers.GameSerializer(game).data, status=status.HTTP_200_OK)
        return Response({'BAD REQUEST': 'INVALID DATA'}, status=status.HTTP_400_BAD_REQUEST)

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.UserView.as_view(), name='view'),
    path('user', views.UserView.as_view(), name='user-view'),
    path('game', views.CreateGame.as_view(), name='create-game')
]

Basically I have 2 models, the User and Game model, I want there to be 1 user that has many games which is why the Game model has a foreign key attached to User, but for some reason it is causing problems in the APIView and returns a 405 not allowed error(at /game)... how can i fix this?

1 Answers

APIView you've implemented has only post() method and get() is unimplemented, therefore you receive such an error. You receive the error because APIView abstracts some parts of the Request and Response handling, but it won't do everything automatically unlike ListCreateAPIView and other generic views.

class CreateGame(APIView): # this is causing problems
    def post(self, request)  # here

Either change to get() if you want to use GET HTTP method or use POST HTTP method instead.

Or better, simply use the ListCreateAPIView and override the post() or create() method. That way you'll have only slight changes instead of custom APIView.

Related