Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 序列化DRF中的自定义相关字段_Python_Json_Django_Serialization_Django Rest Framework - Fatal编程技术网

Python 序列化DRF中的自定义相关字段

Python 序列化DRF中的自定义相关字段,python,json,django,serialization,django-rest-framework,Python,Json,Django,Serialization,Django Rest Framework,我正在尝试创建一个具有嵌套“多对多”关系的序列化程序。目标是获取一个序列化JSON对象,该对象包含一个序列化相关对象的数组。模型如下所示(名称更改,结构保留) 来自django.contrib.auth.models导入用户 PizzaTopping(models.Model): name=models.CharField(最大长度=255) inventor=模型。外键(用户) 比萨饼(型号。型号): name=models.CharField(最大长度=255) 浇头=模型。多个多个字段(比

我正在尝试创建一个具有嵌套“多对多”关系的序列化程序。目标是获取一个序列化JSON对象,该对象包含一个序列化相关对象的数组。模型如下所示(名称更改,结构保留)

来自django.contrib.auth.models导入用户
PizzaTopping(models.Model):
name=models.CharField(最大长度=255)
inventor=模型。外键(用户)
比萨饼(型号。型号):
name=models.CharField(最大长度=255)
浇头=模型。多个多个字段(比萨浇头)
传入的JSON如下所示

{
“名字”:“我的披萨”,
“浇头”:[
{“name”:“cheese”,“inventor”:“bob”},
{“姓名”:“西红柿”,“发明家”:“爱丽丝”}
]
}
我当前的序列化程序代码如下所示

class ToppingRelatedField(RelatedField):
def get_queryset(自我):
返回Topping.objects.all()
def到_表示(自身、实例):
返回{'name':instance.name,'inventor':instance.inventor.username}
def至_内部_值(自身、数据):
name=data.get('name',无)
inventor=data.get('inventor',无)
尝试:
user=user.objects.get(用户名=inventor)
除Setting.DoesNotExist外:
引发序列化程序。ValidationError('bad inventor')
返回顶部(名称=名称,inventor=用户)
类PizzaSerializer(ModelSerializer):
toppings=ToppingRelatedField(多个=真)
类元:
型号=比萨饼
字段=(‘名称’、‘浇头’)
似乎因为我为自定义字段定义了to_internal_value(),它应该自动创建/更新多对多字段。但是当我尝试创建Pizza时,我得到了“无法添加”:字段“pizzatopping”的值是None“ValueError”。看起来在内心深处,Django决定用模型名调用多对多字段。我怎样才能说服它呢

编辑#1:似乎这可能是Django或DRF中某个地方的一个真正的bug。DRF似乎做了正确的事情,它检测到它正在处理一个多个字段,并尝试使用自定义字段从数据中创建浇头并将其添加到比萨饼中。因为它只有一个pizza实例和一个字段名,所以它使用
setattr(pizza,'toppings',toppings)
来完成。Django似乎在做正确的事情。定义了
\uuuuuuuuuuuuuuuuuu\uuuuuuu
,似乎发现它需要在管理器中使用add()方法。但在此过程中,字段名“toppings”会丢失并被默认值替换。即“相关型号名称小写”


编辑2:我找到了一个解决办法。一旦我被允许,我会在回答中记录下来。似乎
RelatedField
子类中的
to\u internal\u value()
方法需要返回一个已保存的Topping实例,以使许多东西正常工作。现有的文档显示了相反的情况,一个this link()示例显然返回了一个未保存的实例。

似乎有一个未记录的需求。对于使用自定义多个字段的写入操作,自定义字段类
to_internal_value()
方法需要在返回实例之前保存实例。DRF文档省略了这一点,创建自定义字段(at)的示例显示了返回未保存实例的方法。我将更新我与DRF团队一起打开的问题。

我也尝试将多个字段返回为json,但得到错误
不可损坏的类型:“dict
。最后,我发现我的方法有什么问题-

RelatedFields通常将相关对象表示为单个值 (例如,slug、主键、url等)。如果你想提供一个 嵌套对象表示,则应使用


您好,我想实施您的解决方案。关联字段的定义是什么?我在文件中找不到。你能提供一个实施的例子吗。谢谢