【发布时间】:2022-01-07 22:03:35
【问题描述】:
对于我的项目,我需要一个简单的流程 一个表单 => 许多问题 => 对于每个问题一个响应类型 => 如果响应类型是多项选择,则可能的响应在一个 uniq 组中。 我的目标是能够推动整个初始形式的 DRF/Django 休息框架。
这是我的模型:
class FormModels(models.Model):
class Status(models.IntegerChoices):
DRAFT = 1, _("DRAFT")
PUBLISHED = 2, _("PUBLISHED")
ARCHIVED = 5, _("ARCHIVED")
form_name = models.CharField(unique=True, blank=False, null=False, max_length=255)
form_model = models.CharField(unique=True, blank=False, null=False, max_length=255)
status = models.IntegerField(choices=Status.choices, blank=False, null=False, default=1)
def __str__(self):
return self.form_name
class FormResponseTypeModels(models.Model):
class Type(models.IntegerChoices):
TEXT = 1, _('TEXT')
MULTICHOICE = 2, _('MULTI')
type = models.IntegerField(choices=Type.choices, blank=False, null=False, default=1)
group = models.IntegerField(blank=False, null=True, default=1)
def __str__(self):
return str(self.type)
class Meta:
constraints = [
UniqueConstraint(fields=['group'], name='unique_group')
]
class MultipleChoiceDataModels(models.Model):
text = models.CharField(blank=False, null=False, max_length=255)
value = models.CharField(blank=False, null=False, max_length=255)
order = models.IntegerField(blank=False, null=False, default=1)
group_refid = models.ForeignKey(blank=False,
null=False,
default=1,
to=FormResponseTypeModels,
to_field="group",
related_name="groups",
on_delete=models.PROTECT)
def __str__(self):
return self.text
class FormQuestionModels(models.Model):
form_id = models.ForeignKey(to=FormModels, on_delete=models.PROTECT)
form_response_type = models.ForeignKey(to=FormResponseTypeModels, on_delete=models.PROTECT, related_name="test")
form_question = models.TextField(max_length=2000)
def __str__(self):
return self.form_question
这是我的 serializers.py
>class FormMultipleChoiceDataSerializer(serializers.ModelSerializer):
class Meta:
model = MultipleChoiceDataModels
fields = "__all__"
depth = 10
class FormResponseTypeSerializer(serializers.ModelSerializer):
groups = FormMultipleChoiceDataSerializer(many=True,
read_only=False,
required=False,
)
class Meta:
model = FormResponseTypeModels
fields = "__all__"
depth = 10
class FormQuestionSerializer(serializers.ModelSerializer):
form_response_type_set = FormResponseTypeSerializer(many=False,
read_only=False,
required=False
)
class Meta:
model = FormQuestionModels
fields = "__all__"
depth = 10
class FormSerializer(serializers.HyperlinkedModelSerializer):
questions = FormQuestionSerializer(many=True,
read_only=False,
source='formquestionmodels_set',
required=False)
class Meta:
model = FormModels
fields = "__all__"
def validate(self, attrs):
pass
return super().validate(attrs=attrs)
def create(self, validated_data):
# https://stackoverflow.com/questions/58023503/drf-serializer-field-renamed-to-its-source-in-validated-data
# question is 'formquestionmodels_set'
questions_data = validated_data.pop('formquestionmodels_set')
form = FormModels.objects.create(**validated_data)
for question_data in questions_data:
if "form_response_type_set" in questions_data:
form_response_type_set = question_data.pop("form_response_type_set")
max_group_id = None
if "formmultiplechoicedatamodel_set" in form_response_type_set:
form_response_type_set_groups = form_response_type_set.pop("formmultiplechoicedatamodel_set")
# find max group_id + 1
max_group_id = 1 + MultipleChoiceDataModels.objects.aggregate(Max("group_refid"))
for form_response_type_set_group in form_response_type_set_groups:
MultipleChoiceDataModels.objects.create(group_refid=max_group_id,
**form_response_type_set_group)
if max_group_id:
form_response_type = FormResponseTypeModels.objects.create(group=max_group_id,
**form_response_type_set)
else:
form_response_type = FormResponseTypeModels.objects.create(**form_response_type_set)
FormQuestionModels.objects.create(form_id=form, form_response_type=form_response_type, **question_data)
return form
预期结果是:
{
"form_name": "test7",
"form_model": "test7",
"status": 1,
"questions": [
{
"form_question": "q1",
"form_response_type_set": {
"type": 1,
"group": [
{
"text": "a",
"value": "1",
"order": 1,
"group_refid": 1
}
]
}
},
{
"form_question": "q2",
"form_id": {
"form_name": "form_name",
"form_model": "form_model",
"status": 1
},
"form_response_type_set": {
"type": 1,
"group": [
{
"text": "a",
"value": "1",
"order": 1,
"group_refid": 1
}
]
}
}
]
}
但是对于组部分,我无法显示它。我得到了:
"questions": [
{
"id": 1,
"form_question": "q1",
"form_id": {
"id": 1,
"form_name": "t1",
"form_model": "t1",
"status": 2
},
"form_response_type": {
"id": 1,
"type": 1,
"group": null
}
},
{
"id": 2,
"form_question": "q2",
"form_id": {
"id": 1,
"form_name": "t1",
"form_model": "t1",
"status": 2
},
"form_response_type": {
"id": 2,
"type": 2,
"group": 1
}
}
],
"form_name": "t1",
"form_model": "t1",
"status": 2
}
]
使用 django shell 我得到这个结果:
FormResponseTypeSerializer():
id = IntegerField(label='ID', read_only=True)
groups = FormMultipleChoiceDataSerializer(many=True, read_only=False, required=False):
id = IntegerField(label='ID', read_only=True)
text = CharField(max_length=255)
value = CharField(max_length=255)
order = IntegerField(max_value=2147483647, min_value=-2147483648, required=False)
group_refid = NestedSerializer(read_only=True):
id = IntegerField(label='ID', read_only=True)
type = ChoiceField(choices=[(1, 'TEXT'), (2, 'MULTI')], required=False, validators=[<django.core.validators.MinValueValidator object>, <django.core.validators.MaxValueValidator object>])
group = IntegerField(allow_null=True, max_value=2147483647, min_value=-2147483648, required=False)
type = ChoiceField(choices=[(1, 'TEXT'), (2, 'MULTI')], required=False, validators=[<django.core.validators.MinValueValidator object>, <django.core.validators.MaxValueValidator object>])
group = IntegerField(allow_null=True, max_value=2147483647, min_value=-2147483648, required=False)
我已经尝试过源和相关名称、许多类型的序列化程序、变量源的 _set 语法 ... ,阅读了 40 多个堆栈溢出线程,但每次我都被这个问题困扰(另外,如果重要的话,我希望能够使用相同的端点一次发布新表单)
你能指出我的错误吗?
【问题讨论】:
标签: python django django-rest-framework