您好,
您能帮助我禁用创建嵌套对象吗?
我有这样的序列化程序:
(员工对团队有ForeignKey)
class TeamSerializer(serializers.ModelSerializer):
class Meta:
model = Team
fields = ('id', 'name')
class EmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
fields = ('id', 'name', 'surname', 'team')
depth = 1
或者可能是:
class EmployeeSerializer(serializers.ModelSerializer):
team = TeamSerializer()
class Meta:
model = Employee
fields = ('id', 'name', 'surname', 'team')
当我发布json(创建员工)
{
name: "name",
surname: "surname",
team: {
id: 1,
name: "Web Team"
}
}
对象员工创建但也是对象团队...... 有没有办法禁止与员工一起创建团队对象? 我只想创建员工并将选定的团队(在数据库中)设置为员工
在GET(列表)上,我希望能够检索 数据如:
{
name: "name",
surname: "surname",
team: {
id: 1,
name: "Web Team"
}
不喜欢
{
name: "name",
surname: "surname",
team: 1
}
在django rest框架中是否有任何方法(也使用angular)
此致
目前序列化器:
class TeamSerializer(serializers.ModelSerializer):
class Meta:
model = Team
class EmployeeSerializer(serializers.ModelSerializer):
team = TeamSerializer()
class Meta:
model = Employee
我不能使用serializers.RelatedField(),因为它只返回 unicode 我需要'id'和'name'(我想)
这是我的POST json :( Restangular.all('employee')。post(data))
data: {
name: "emp1",
photo: "",
skype: "",
surname: "qweqwe",
team: {
id: 1,
name: "Web",
}
}
和DRF返回了json:
employee: {
id: 2,
name: "emp1",
photo: "",
skype: "",
surname: "qweqwe",
team: {
id:3, <-- NEW ID!
name: "Web"
}
}
所以是的,我确信创建了新的团队对象。那么现在呢?:)
答案 0 :(得分:2)
我发现最新版本的DRF中不存在ModelSerializer.to_native()
和ModelSerializer.from_native()
。我想出了以下解决方案得出的以下内容:
class PlayerSerializer(serializers.ModelSerializer):
class Meta:
model = Player
fields = ('id', 'name', 'team')
def to_internal_value(self, data):
# If team is not a dict, such as when submitting via the Browseable UI, this would fail.
try:
data['team'] = data['team']['id']
except TypeError:
pass
return super(PlayerSerializer, self).to_internal_value(data)
def to_representation(self, instance):
return ReadPlayerSerializer(instance).data
class ReadPlayerSerializer(serializers.ModelSerializer):
team = TeamSerializer()
class Meta(PlayerSerializer.Meta):
pass
实际上,from_native
现在to_representation
似乎to_native
不是to_internal_value
答案 1 :(得分:1)
好的,首先,您确定已创建嵌套对象吗?因为DRF不是为了创建嵌套对象而设计的,所以这是一种非常奇怪的行为(更确切地说,这是work in progress,正如其创建者Tom Christie所说的那样。
然后,为了获得所需的序列化程序表示,您必须遵循一些规则:
为每个模型创建一个简单的序列化程序(就像在第一个代码段中一样)
在EmployeeSerializer上添加FK关系:(小心,要使其正常工作,您必须将您的FK命名为'team') team = serializers.RelatedField()
此外,您应该从序列化程序中删除 depth 属性,他是使序列化变得扁平化的属性(或者您可以将其设置为2)。希望这会有所帮助。
<强>更新强>
查看多个序列化程序:
def get_serializer_class(self):
if self.request.method == 'GET':
return ReadEmployeeSerializer
elif self.request.method == 'POST':
return WriteEmployeeSerializer
else:
return DefaultSerializer
class WriteEmployeeSerializer(serializers.ModelSerializer):
class Meta:
model = Employee
fields = ('id', 'name', 'surname', 'team')
class ReadEmployeeSerializer(serializers.ModelSerializer):
team = TeamSerializer()
class Meta:
model = Employee
fields = ('id', 'name', 'surname', 'team')
有点多余,但应该做好工作。
答案 2 :(得分:0)
解决问题:
class ReadEmployeeSerializer(serializers.ModelSerializer):
team = TeamSerializer()
class Meta:
model = Employee
fields = ('id', 'name', 'surname', 'team',)
class WriteEmployeeSerializer(serializers.ModelSerializer):
def from_native(self, data, files):
data['team'] = data['team']['id']
return serializers.ModelSerializer.from_native(self, data, files)
def to_native(self, obj):
return ReadEmployeeSerializer(obj).data
class Meta:
model = Employee
fields = ('id', 'name', 'surname', 'team',)
post / put方法使用主键(WriteEmployeeSerializer) - 在将dict替换为主键之前
get方法使用完整对象(ReadEmployeeSerializer)