组合序列化器和模型函数
Combining serializer and model functions
我有两个序列化程序...MyRegisterSerializer
继承并扩展了一个流行的 app/package,django-rest-auth,它连接到一个相当标准的用户 table。我还有一个用于自定义应用程序的模型和序列化程序,TeamSerializer(与用户的一对多关系)。当用户注册时,我希望他们能够同时加入一个团队,所以我需要以某种方式创建一个团队,return 团队 ID,然后将该 ID 传递给 RegisterSerializer,这样团队的 ID 可以存储在 User table 中。我知道我可以进行两次调用,首先是创建团队和 return 值,然后将其传递给寄存器序列化程序,但是有没有一种方法可以在一个序列化程序中完成这一切?我是 python 的 n00b,并且找不到一个很好的例子,考虑到我必须 return 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', '')
}
这取决于你想如何创建团队:
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
我不确定你到底需要什么。如果您需要进一步的帮助,请告诉我。
我有两个序列化程序...MyRegisterSerializer
继承并扩展了一个流行的 app/package,django-rest-auth,它连接到一个相当标准的用户 table。我还有一个用于自定义应用程序的模型和序列化程序,TeamSerializer(与用户的一对多关系)。当用户注册时,我希望他们能够同时加入一个团队,所以我需要以某种方式创建一个团队,return 团队 ID,然后将该 ID 传递给 RegisterSerializer,这样团队的 ID 可以存储在 User table 中。我知道我可以进行两次调用,首先是创建团队和 return 值,然后将其传递给寄存器序列化程序,但是有没有一种方法可以在一个序列化程序中完成这一切?我是 python 的 n00b,并且找不到一个很好的例子,考虑到我必须 return 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', '')
}
这取决于你想如何创建团队:
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
我不确定你到底需要什么。如果您需要进一步的帮助,请告诉我。