Rest-API post request fail with one-to-many в Django REST Framework

Я хочу добавить в свой API возможность добавления записи с внешним ключом. Я не хочу создавать новую запись в связанной таблице. Я просто хочу добавить ID существующей записи в отношение и сохранить запись. Отношение показано на следующем графике. Диаграмма

Например, запрос Get к акрониму возвращает следующий ответ:

{
        "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
        }
    },

С другой стороны, я бы хотел, чтобы пост можно было написать в следующем формате:

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

Соответствующая часть представления (view.py) выглядит следующим образом:

@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)

В serialzier моя идея заключалась в том, чтобы использовать отдельный сериализатор scope для команды post, чтобы включить формат, поскольку в противном случае валидатор выдавал ошибку, что "ветка" не была заполнена. Соответствующая часть сериализатора (serializer.py) выглядит следующим образом:

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()

Запрос post проходит через валидатор, но когда я обращаюсь к json в функции create, запись выглядит следующим образом:

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

Orderdict в Scope пуст -> odict_items([])

Где моя ошибка? Или я не понял чего-то фундаментального? (Я все еще новичок в Django и остальных фреймворках)

Я наконец-то нашел решение. Оказывается, существует гораздо более простое решение моей проблемы:

(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)
Вернуться на верх