500 ошибка Django Rest Frameworks Serializer
новичок. Я следую учебнику по React+Django (создание магазина), в котором мы используем Django RestFrameworks (и это мой первый раз, когда я его использую). Мы используем сериализаторы с JWT-токенами для аутентификации. Проблема в том, что когда я пытаюсь создать новый "заказ" на странице, я получаю ошибку 500:
Мой файл serializers.py выглядит следующим образом:
from rest_framework import serializers
from django.contrib.auth.models import User
from rest_framework_simplejwt.tokens import RefreshToken
from .models import Product, Order, OrderItem, ShippingAddress
class UserSerializer(serializers.ModelSerializer):
name = serializers.SerializerMethodField(read_only = True)
isAdmin = serializers.SerializerMethodField(read_only = True)
class Meta:
model = User
fields= ['id', 'first_name','email', 'name', 'isAdmin']
def get_isAdmin(self, obj):
return obj.is_staff
def get_name(self, obj):
name = obj.first_name
if name == '':
name = obj.email
return name
class UserSerializerWithToken(UserSerializer):
token = serializers.SerializerMethodField(read_only = True)
class Meta:
model=User
fields = ['id', 'username', 'email', 'name', 'isAdmin', 'token']
def get_token(self, obj):
token = RefreshToken.for_user(obj)
return str(token.access_token)
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields= '__all__'
class ShippingAddressSerializer(serializers.ModelSerializer):
class Meta:
model = ShippingAddress
fields= '__all__'
class OrderItemSerializer(serializers.ModelSerializer):
class Meta:
model = OrderItem
fields= '__all__'
class OrderSerializer(serializers.ModelSerializer):
orderItems = serializers.SerializerMethodField(read_only = True) #formerly orders
shippingAddress = serializers.SerializerMethodField(read_only = True)
user = serializers.SerializerMethodField(read_only = True)
class Meta:
model = Order
fields= '__all__'
def get_orderItems(self,obj): #former get_orders
items = obj.orderitem_set.all()
serializer = OrderItemSerializer(items, many = True)
return serializer.data
def get_shippingAddress(self,obj):
try:
address = ShippingAddressSerializer(obj.shippingAddress, many=False) #we can do it like this because this is a 1:1 field
except:
address = False
return address
def get_user(self,obj):
user =User.objects.all() #previously obj.user.all(), but that gave an error
serializer = UserSerializer(user, many = False)
return serializer.data
my user_views.py:
from django.shortcuts import render
from django.contrib.auth.hashers import make_password
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.response import Response
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework import status
from base.models import User
from base.serializers import UserSerializer, UserSerializerWithToken
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
data = super().validate(attrs)
serializer = UserSerializerWithToken(self.user).data
for key, value in serializer.items():
data[key]=value
return data
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
@api_view(['POST'])
def registerUser(request):
data=request.data
try:
user=User.objects.create(
first_name = data['first_name'],
#last_name= data['last_name'], this was causing error: fields didn't match
username = data['email'],
email = data['email'],
password = make_password(data['password'])
)
serializer = UserSerializerWithToken(user, many=False)
return Response(serializer.data)
except:
message={'detail':'User with this email already exists'}
return Response(message, status=status.HTTP_400_BAD_REQUEST)
@api_view(['PUT'])
@permission_classes([IsAuthenticated])
def updateUserProfile(request):
user = request.user
serializer = UserSerializerWithToken(user, many=False)
data =request.data
user.first_name=data['first_name']
user.username=data['email']
user.email=data['email']
if data['password'] != ' ' :
user.password = make_password(data['password'])
user.save()
return Response(serializer.data)
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def getUserProfile(request):
user = request.user
serializer = UserSerializer(user, many=False)
return Response(serializer.data)
@api_view(['GET'])
@permission_classes([IsAdminUser])
def getUsers(request):
users = User.objects.all()
serializer = UserSerializer(users, many=True)
return Response(serializer.data)
В этом учебнике мы используем модель Django User по умолчанию.
Пожалуйста, может кто-нибудь подсказать мне, что я делаю не так? Заранее большое спасибо
Как следует из ошибки, вы пытаетесь получить first_name
из Queryset, а не из отдельного экземпляра/объекта.
Это происходит потому, что в методе get_user
вы передаете Queryset
в UserSerializer
, а не объект User
.
Полагаю, что вы пытаетесь передать пользователя, связанного с order
, в UserSerializer
. Если это так, вы можете изменить метод get_user на следующий:
def get_user(self,obj):
serializer = UserSerializer(obj.user)
return serializer.data
Вы можете получить доступ к пользователю по объекту заказа
def get_user(self,obj):
serializer = UserSerializer(obj.user)
return serializer.data