Создание внешних полей в Django сразу после создания объекта

Я получаю входной JSON с полями description и choices для модели Question. Модель Choice также имеет поле внешнего ключа, указывающее на Question со связанным именем choices. Однако в JSON модель Choice будет представлена без поля question_id, чтобы быть назначенной после создания модели Question

Я получаю всевозможные ошибки при попытке создать Question и затем назначить ему все входящие. Много искал ошибку Direct assignment to the forward side и не нашел ничего, что решило бы мою проблему

CreateChoiceSerializer не требует создания question_id, я решаю проблему присвоения Question с помощью context поля

Я не могу изменить связанное имя и поля ввода JSON, если бы это было возможно, я бы уже сделал это

class CreateQuestionSerializer(serializers.ModelSerializer):
    description = serializers.CharField(max_length=1024, allow_blank=False, required=True)
    choices = CreateChoiceSerializer(many=True, required=True)

    def create(self, validated_data):
        choices = validated_data.pop('choices')

        question = Question.objects.create(**validated_data)

        choices_serializer = CreateChoiceSerializer(data=choices, many=True, context={'question': question})
            if choices_serializer.is_valid():
                choices_serializer.save()
        
        return question



На вашем месте я бы использовал эти сериализаторы для создания вопросов со связанными вариантами ответов.

class CreateChoiceSerializer(serializers.ModelSerializer):
    class Meta:
        model = Choice
        fields = "__all__"

class CreateQuestionSerializer(serializers.ModelSerializer):
    description = serializers.CharField(max_length=1024, allow_blank=False, required=True)
    choices = CreateChoiceSerializer(many=True, required=True)

    def create(self, validated_data):
        choices = validated_data.pop('choices')

        question = Question.objects.create(**validated_data)

        choices_model = []
        for choice in choices:
            choices_model.append(Choice(question_id=question.id, **choice))
        Choice.objects.bulk_create(choices_model)
        return question

Если вы вызовете функцию QuestionSerializer.is_valid, она тоже проверит значения вариантов. Поэтому не нужно передавать значения в ChoiceSerializer и снова проверять их в функции QuestionSerializer.create.

Я использую функцию bulk_create, чтобы вставить все варианты сразу.

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

Примечание: скрипт, который я написал, может не совсем подходить к вашему коду. потому что я не знаю, какие у вас модели.

Вернуться на верх