Rest-API post request fails with one-to-many in Django REST Framework

I want to add with my API the possibility to add a record with a foreign key. I don't want to create a new record in the related table. I just want to add the ID of the existing record to the relation and save the record. The relation is shown in the following graphic. Diagram

For example, the Get request to an acronym returns the following response:

{
        "acronym": "Commercial water large stock third letter. Democrat your goal run price. Record myself decision attorney give.\nBill around difficult west protect change every. Various history total particular painting. Mission himself car can of try ten.",
        "decleration": "Less.",
        "date": "1992-02-12",
        "scope": {
            "scope_id": 16
        }
    },

On the other hand, I would like the post to be possible with the following format:

{
    "acronym": "Hello",
    "decleration": "World",
    "date": "2010-07-05",
    "scope": {"scope_id" : 16}
}

The corresponding part of the view (view.py) looks like this:

@api_view(['GET', 'POST'])
def acronym_list(request):
    if request.method == 'GET':
        acronyms = Acronym.objects.all()
        serializer = AcronymSerializer(acronyms, many=True)
        return Response(serializer.data)
    elif request.method == 'POST':
        serializer = AcronymSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

In serialzier my idea was therefore to use a separate scope serializer for the post command to enable the format, since otherwise the validator had thrown an error that "branch" had not been filled. The corresponding part of the serializer (serializer.py) looks like this:

class ScopeInsertSerializer(serializers.ModelSerializer):
    class Meta:
        model = Scope
        fields = ['scope_id']

class AcronymSerializer(serializers.ModelSerializer):
    scope = ScopeInsertSerializer(read_only=False)
    
    class Meta:
        model = Acronym
        depth = 1
        fields = ['acronym', 'decleration', 'date', 'scope']
  
    def create(self, validated_data):
        scope = validated_data.pop('scope')
        acronym = Acronym.objects.create(**validated_data)
        existing_scope = Scope.objects.get(scope_id=scope)
        acronym.scope = existing_scope
        acronym.save()

The post request runs through the validator, but when I access the json in the create function the record looks like this:

{'acronym': 'Hello', 'decleration': 'World', 'date': datetime.date(2010, 7, 5), 'scope': OrderedDict()}

The orderdict in Scope is empty -> odict_items([])

Where is my mistake? Or have I not understood something fundamental? (I am still new to Django and the rest framework)

I have finally found a solution. Turns out there is a much simpler solution to my problem:

(view.py)

@api_view(['PATCH'])
    def add_tag_to_acronym_detail(request, acronym_pk, tag_pk):
        if request.method == 'PATCH':
            acronym = Acronym.objects.get(acronym_id=acronym_pk)
            tag_instance = Tag.objects.get(tag_id=tag_pk)
            acronym.tag.add(tag_instance)
            return Response(status=status.HTTP_204_NO_CONTENT)
        else: 
            return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Back to Top