我有一个创建用户视图,在这里我首先注册一个普通用户,然后为该用户创建一个与用户有fk关系的玩家对象。
就我而言,我有三种不同类型的用户
我创建了一个视图来处理注册所有三种不同类型的用户,但我的播放器用户有很多额外的模型字段,并且将所有查询参数存储在变量中会使其变得混乱。
有没有更好的方法来处理这个问题,包括验证?
TLDR;我创建了一个视图来处理注册所有三种不同类型的用户,但我的播放器用户有很多额外的模型字段,并且将所有查询参数存储在变量中会使其变得混乱。有没有更好的方法来处理这个问题,包括验证?
这是我的观点。
class CreateUser(APIView):
"""
Creates the User.
"""
def post(self, request):
email = request.data.get('email', None).strip()
password = request.data.get('password', None).strip()
name = request.data.get('name', None).strip()
phone = request.data.get('phone', None)
kind = request.query_params.get('kind', None).strip()
print(kind)
serializer = UserSerializer(data={'email': email, 'password':password})
serializer.is_valid(raise_exception=True)
try:
User.objects.create_user(email=email,
password=password)
user_obj = User.objects.get(email=email)
except:
raise ValidationError('User already exists')
if kind == 'academy':
Academy.objects.create(email=email, name=name, phone=phone, user=user_obj)
if kind == 'coach':
Coach.objects.create(email=email, name=name, phone=phone, user=user_obj)
if kind == 'player':
Player.objects.create(----------)
return Response(status=200)
答案 0 :(得分:1)
在您的情况下,请在serializers.py
中定义,如下所示:
from rest_framework import serializers
class CustomBaseSerializer(serializers.ModelSerializer):
def create(self, validated_data):
validated_data['user'] = self.context['user']
return super(CustomBaseSerializer, self).create(validated_data)
class PlayerSerializer(CustomBaseSerializer):
class Meta:
model = Player
fields = ('count', 'height', 'right_handed', 'location',
'size', 'benchmark_swingspeed',
'benchmark_impactspeed', 'benchmark_stance',
'benchmark_balanceindex',)
class AcademySerializer(CustomBaseSerializer):
class Meta:
model = Academy
fields = '__all__' # Usually better to explicitly list fields
class CoachSerializer(CustomBaseSerializer):
class Meta:
model = Coach
fields = '__all__'
然后在你看来
class CreateUser(APIView):
"""
Creates the User.
"""
def post(self, request):
print(kind)
try:
user = User.objects.get(email=request.data.get('email'))
except User.DoesNotExist:
pass
else:
raise ValidationError('User already exists')
user_serializer = UserSerializer(data=request.data)
user_serializer.is_valid(raise_exception=True)
user = user_serializer.save()
if kind == 'academy':
serializer_class = AcademySerializer
if kind == 'coach':
serializer_class = CoachSerializer
if kind == 'player':
serializer_class = PlayerSerializer
serializer = serializer_class(data=request.data, context={'user': user})
serializer.save()
return Response(serializer.data) # Status is 200 by default so you don't need to include it. RESTful API's should return the instance created, this also delivers the newly generated primary key back to the client.
# Oh and if you do serialize the object in the response, write serializers for academy and coach too, so the api response is consistent
序列化程序非常强大且有用。非常值得仔细阅读文档。
答案 1 :(得分:0)
首先,我建议以JSON或表单POST参数,而不是使用查询参数。但无论方法如何,解决方案都差不多。
首先,您可以在列表中定义您感兴趣的字段。例如:
FIELDS = (
'count',
'height',
'right_handed',
'location',
'size',
'benchmark_swingspeed',
'benchmark_impactspeed',
'benchmark_stance',
'benchmark_balanceindex',
)
然后从查询参数获取所有值并将它们存储在dict中,例如:
player_params = {}
for field in FIELDS:
player_params[field] = request.query_params.get(field)
现在你拥有了一个玩家在dict中所需的所有参数,你可以将它作为** kwargs传递给玩家模型。当然你可能需要一些验证。但最后,你将能够做到以下几点:
Player.objects.create(user=user_obj, **player_params)