Django 处理多个查询参数

Django 处理多个查询参数,django,django-models,django-rest-framework,Django,Django Models,Django Rest Framework,我有一个创建用户视图,在这里我首先注册一个普通用户,然后为该用户创建一个与该用户有fk关系的播放器对象 在我的例子中,我有三种不同类型的用户 我创建了一个视图来处理注册所有三种不同类型的用户,但是我的播放器用户有很多额外的模型字段,将所有查询参数存储在变量中会使它变得混乱 有没有更好的方法来处理这个问题,包括验证 TLDR;我创建了一个视图来处理注册所有三种不同类型的用户,但是我的播放器用户有很多额外的模型字段,将所有查询参数存储在变量中会使它变得混乱。有没有更好的方法来处理这个问题,包括验证

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

首先,我建议将参数发布在JSON或表单中,而不是使用查询参数。但不管采用哪种方法,解决方案基本相同

首先,可以在列表中定义感兴趣的字段。例如:

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)
使用

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

序列化程序非常强大和有用。非常值得仔细阅读这些文档。

您为什么不在这里使用ModelSerializer?非常感谢您的详细回答,非常感谢。我正在阅读文档,并使用模型序列化器完成了类似的实现,但您的实现要好得多,给了我更多的想法。阅读文档真的很有帮助:无论如何,我得到了一个新的错误:{user:[这个字段是必需的。]}但是我正在传递用户serializer=serializer\u classdata=request.data,context={'user':user}无论如何我已经解决了这个问题,必须排除序列化程序中的用户,并且没有从自定义基序列化程序返回对象实例。感谢您的反馈!对不起那些小虫子:S