处理多个查询参数

时间:2018-03-06 18:59:48

标签: django django-models django-rest-framework

我有一个创建用户视图,在这里我首先注册一个普通用户,然后为该用户创建一个与用户有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)

2 个答案:

答案 0 :(得分:1)

使用Model Serializer

在您的情况下,请在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)