分析
总之,预计下面的内容将起作用,下面将介绍解决方案。我已经离开了这个问题,万一其他人都迷失了。
原始问题
在Django M2M教程中,我们有比萨饼和浇头。作为我的应用程序的一部分,我有一些是M2M字段的顶部,以及一个添加新顶部的端点。但是,我只想添加顶部,如果它还不存在,否则我只想返回现有的顶部。这是为了避免Pizzas和Toppings之间的嵌套-M2M关系导致问题,而是我有两个端点,一个用于比萨饼,一个用于浇头,然后在视图中添加post_save
浇头。
但是,以下似乎不起作用:
class ToppingSerializer(serializers.ModelSerializer):
another_model = serializers.PrimaryKeyRelatedField()
class Meta:
model = Topping
fields = ('id', 'another_model', 'name')
def save_object(self, obj, **kwargs):
topping = Topping.objects.get_or_create(another_model=obj.another_model,
name=obj.name)
return topping
使用以下视图代码:
[snip - View code below]
serializer_class = ToppingSerializer
serializer = self.get_serializer(data=request.DATA, many=True)
if serializer.is_valid():
serializer.save()
return Response(status=status.HTTP_201_CREATED)
[snip]
答案 0 :(得分:1)
我认为您需要更改句子并在“serializer.objects”末尾添加“.all()”:
for topping in ToppingSerializer.objects.all():
print topping.id
小心大写字母。要获取类的所有对象,您需要调用该类。如果你定义像ToppingSerializer这样的类,要获取该类的所有对象,你必须调用“ToppingSerializer.objects.all()”,你将得到一个对象列表作为返回。
答案 1 :(得分:0)
总之,上述应该可以工作,因为在相关的self.object上调用了save()和save_object()调用,并且不返回任何内容。因此,应该预期上述方法不起作用。相反,在重写的save()方法中迭代self.object列表,并用这个替换pre-save self.object列表,就可以了。这就是诀窍。
以下是一个例子:
def save(self, **kwargs):
"""
Unintelligent save via get_or_create(). This does not handle logic
for adding/removing toppings from parent (read pizza) models. It
merely puts new toppings into the database.
"""
# Clear cached _data, which may be invalidated by `save()`
self._data = None
if isinstance(self.object, list):
saved_mappings = [Topping.objects.get_or_create(another_model=item.another_model, name=item.name)[0] for item in self.object]
else:
saved_mappings = Topping.objects.get_or_create(another_model=self.object.another_model, name=self.object.name)
self.object = saved_mappings
return self.object