Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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 Django rest框架以编程方式填充嵌套对象的字段_Python_Django_Django Rest Framework - Fatal编程技术网

Python Django rest框架以编程方式填充嵌套对象的字段

Python Django rest框架以编程方式填充嵌套对象的字段,python,django,django-rest-framework,Python,Django,Django Rest Framework,当需要在Django Rest Framework中以编程方式填充字段时,pre_save方法可以在APIView中被重写,并且所需的字段可以在那里填充,如: def pre_save(self, obj): obj.owner = self.request.user 这对于平面对象非常有效,但在嵌套的情况下,无法使用pre_save方法访问嵌套对象。到目前为止,我找到的唯一解决方案是重写save_object方法,检查该对象是否是嵌套类的实例,如果是,则填充该字段。虽然这是可行的,但

当需要在Django Rest Framework中以编程方式填充字段时,
pre_save
方法可以在
APIView
中被重写,并且所需的字段可以在那里填充,如:

def pre_save(self, obj):
    obj.owner = self.request.user
这对于平面对象非常有效,但在嵌套的情况下,无法使用
pre_save
方法访问嵌套对象。到目前为止,我找到的唯一解决方案是重写
save_object
方法,检查该对象是否是嵌套类的实例,如果是,则填充该字段。虽然这是可行的,但我不喜欢这个解决方案,我想知道是否有人找到了更好的方法

展示情况:

class Notebook(models.Model):
    owner = models.ForeignKey(User)

class Note(models.Model):
    owner = models.ForeignKey(User)
    notebook = models.ForeignKey(Notebook)
    note = models.TextField()

class NoteSerializer(serializers.ModelSerializer):
    owner = serializers.Field(source='owner.username')
    class Meta:
        model = Note
        fields = ('note', 'owner')

class NotebookSerializer(serializers.ModelSerializer):
    notes = NoteSerializer(many=True)
    owner = serializers.Field(source='owner.username')
    class Meta:
        model = Notebook
        fields = ('notes', 'owner')

    def save_object(self, obj, **kwargs):
        if isinstance(obj, Note):
            obj.owner = obj.notebook.owner

        return super(NotebookSerializer, self).save_object(obj, **kwargs)

class NotebookCreateAPIView(CreateAPIView):
    model = Notebook
    permission_classes = (IsAuthenticated,)
    serializer_class = NotebookSerializer

    def pre_save(self, obj):
        obj.owner = self.request.user
在问我为什么不使用不同的端点分别创建笔记本和笔记之前,让我说我这样做了,但我还需要一个功能来提供创建笔记本的初始笔记,所以我也需要这种端点

另外,在我想出这个骇人的解决方案之前,我实际上预计我将不得不重写
NoteSerializer
类本身的
save_object
方法,但事实证明,对于嵌套对象,它甚至不会被调用,对于所有嵌套对象,只调用根对象的
save_objects
方法,但我想这是一个设计决定


那么,这是否可以用更惯用的方式解决呢?

您可以在序列化程序上下文中访问请求

因此,我的方法是:

class NoteSerializer(serializers.ModelSerializer):
    owner = serializers.Field(source='owner.username')

    def restore_object(self, attrs, instance=None):
        instance = super(NoteSerializer, self).restore_object(attrs, instance)
        instance.owner = self.context['request'].user
        return instance

    class Meta:
        model = Note
        fields = ('note', 'owner')
NotebookSerializer
上也是如此


序列化程序上下文将对
视图集中所有使用的序列化程序可用

妈的,这看起来真的很好,我会试试看,然后再给你回复,谢谢你