Создание внешних полей в 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
, чтобы быть уверенным, что вопрос и связанные с ним варианты выбора всегда создаются безопасно, а не являются их частью.
Примечание: скрипт, который я написал, может не совсем подходить к вашему коду. потому что я не знаю, какие у вас модели.