Django rest structure fills fields of nested objects programmatically

When fields need to be populated programmatically in the Django Rest Framework, the method pre_savecan be overridden in APIView, and the required fields can be filled there, for example:

def pre_save(self, obj):
    obj.owner = self.request.user

This is great for flat objects, but in case of nested situations, access to the nested object is not possible in the method pre_save. The only solution I have found so far is to override the method save_objectand check if the object is an instance of a nested class, and if so, fill in this field. Although this works, I don't like the solution, and would like to know if anyone has found a better way?

Demonstration of the situation:

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

, , , , , , .

, , , save_object NoteSerializer, , save_objects , , , .

, , ?

+4
1

.

, :

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.

Serializer ViewSet.

+3

Source: https://habr.com/ru/post/1529767/


All Articles