【问题标题】:Combining serializer and model functions结合序列化器和模型函数
【发布时间】:2019-11-20 17:21:01
【问题描述】:

我有两个序列化程序...MyRegisterSerializer 继承并扩展了一个流行的应用程序/包 django-rest-auth,它连接到一个相当标准的用户表。我还有一个自定义应用程序的模型和序列化程序,TeamSerializer(与用户的一对多关系)。当用户注册时,我希望他们能够同时加入一个团队,所以我需要创建一个团队,返回团队 ID,然后将该 ID 传递给 RegisterSerializer,以便团队可以存储在用户表中。我知道我可以进行两次调用,首先创建团队并返回值,然后将其传递给寄存器序列化程序,但是有没有办法在一个序列化程序中完成这一切?我是 python 的 n00b,找不到一个很好的例子,考虑到我必须按原样返回 get_cleaned_data() 函数。谢谢!

class TeamSerializer(serializers.ModelSerializer):

  class Meta:
    model = Team
    fields = ('id', 'name', 'logo', 'user')

class MyRegisterSerializer(RegisterSerializer):
  first_name = serializers.CharField()
  last_name = serializers.CharField()

  def get_cleaned_data(self):
    super(MyRegisterSerializer, self).get_cleaned_data()
    return {
        'team_id': <How do I get this value>
        'username': self.validated_data.get('username', ''),
        'position': self.validated_data.get('password1', ''),
        'email': self.validated_data.get('email', ''),
        'first_name': self.validated_data.get('first_name', ''),
        'last_name': self.validated_data.get('last_name', '')
    }

【问题讨论】:

    标签: python django django-allauth serialization django-rest-auth


    【解决方案1】:

    这取决于你想如何创建团队:

    1。团队是由其他一些信息创建的:

    您应该可以使用此自定义字段:

    from rest_framework.relations import PrimaryKeyRelatedField
    
    class TeamPrimaryKeyRelatedField(PrimaryKeyRelatedField):
        def to_internal_value(self, data):
            if self.pk_field is not None:
                data = self.pk_field.to_internal_value(data)
            try:
                obj, created = self.get_queryset().get_or_create(
                    pk=data,
                    defaults=get_team_data(),
                )
                return obj
            except (TypeError, ValueError):
                self.fail('incorrect_type', data_type=type(data).__name__)
    

    并在您的序列化器中使用它:

    class MyRegisterSerializer(RegisterSerializer):
        team = TeamPrimaryKeyRelatedField()
        # ...
    

    2。使用额外的用户输入来创建团队:

    这看起来像是 writable nested serializers 的完美用例:

    class TeamSerializer(serializers.ModelSerializer):
        class Meta:
            model = Team
            fields = ('id', 'name', 'logo', 'user')
    
    class MyRegisterSerializer(RegisterSerializer):
      first_name = serializers.CharField()
      last_name = serializers.CharField()
      team = TeamSerializer()
    
        def create(self, validated_data):
            team_data = validated_data.pop('team')
            # You could do this if the user is not necessary in the team object:
            team = Team.objects.create(**team_data)
            user = super().create(team=team, **validated_data)
    
            # Otherwise:
            user = super().create(**validated_data)
            # Should this be a many-to-many relationship?
            team = Team.objects.create(user=user, **team_data)
            # I don't know if this works/you need it:
            self.team = team
            # Or it should be like this?
            self.validated_data['team'] = team
            return user
    

    我不确定您到底需要什么。如果您需要进一步的帮助,请告诉我。

    【讨论】:

    • 我的答案看起来与您的第二种方法非常相似,我相信这就是 OP 正在寻找的。​​span>
    猜你喜欢
    • 2014-06-10
    • 1970-01-01
    • 2023-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    相关资源
    最近更新 更多