Django 3.2 inline_formset со связанными моделями многие к одному
Я хотел бы, чтобы моя форма выглядела следующим образом enter image description here. но при таком подходе мой вывод выглядит следующим образом enter image description here
Вот мои модели
class Question(models.Model):
id = models.BigAutoField(primary_key=True)
question = models.CharField(max_length=255, unique=True)
is_active = models.BooleanField(default=False)
class Declaration(models.Model):
id = models.BigAutoField(primary_key=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='declarations', on_delete=models.CASCADE)
created_at = models.DateTimeField(verbose_name='created', auto_now_add=True)
class Checklist(models.Model):
id = models.BigAutoField(primary_key=True)
declaration = models.ForeignKey(Declaration, related_name='checklist_declarations', on_delete=models.CASCADE)
question = models.ForeignKey(Question, related_name='checklist_questions', on_delete=models.CASCADE, limit_choices_to={'is_active': 'True'})
is_yes = models.BooleanField()
формы
class ChecklistInlineFormSet(BaseInlineFormSet):
def clean(self):
if any(self.errors):
#Don't bother validating the formset unless each form is valid on its own
return
questions = []
for form in self.forms:
question = form.cleaned_data.get('question')
if question in questions:
raise ValidationError(_('Question must be distinct'), code='invalid')
questions.append(question)
class HorizontalRadionRenderer(forms.RadioSelect):
def render(self):
return mark_safe(u'\n'.join([u'%s\n' % w for w in self]))
class ChecklistForm(forms.ModelForm):
ANSWER_CHOICES = [
(True, 'Yes'),
(False, 'No')
]
is_yes = forms.TypedChoiceField(
choices=ANSWER_CHOICES,
coerce=lambda x: x == 'True',
widget=forms.RadioSelect,
required=True
)
class Meta:
model = Checklist
fields = ['question', 'is_yes']
просмотров
declaration.views
def checklist(request):
FS_PREFIX = 'question_fs'
user = request.user
result = ""
if request.method == 'POST':
# Use your custom FormSet class as an argument to inlineformset_factory
formset = inlineformset_factory(Declaration, Checklist, form=ChecklistForm, fk_name='declaration', formset=ChecklistInlineFormSet)
declaration = Declaration()
declaration.user = user
checklist = formset(request.POST, prefix=FS_PREFIX, instance=declaration)
char = request.POST
print(char)
if checklist.is_valid():
with transaction.atomic():
declaration.save()
checklist.declaration = declaration
checklist.save()
result = 'true'
#Updates profile's health status based on declaration submitted
declaration.health_status()
return result
else:
print(checklist.errors)
print(checklist.non_form_errors())
print('checklist form invalid')
messages.add_message(request, messages.ERROR, 'Checklist invalid! Make sure to answer the questions legitimately.')
questions = []
questions = [{'question': str(q.id),'is_yes': None} for q in Question.objects.all().order_by('ordering')]
formset = inlineformset_factory(Declaration, Checklist, form=ChecklistForm, fk_name="declaration", extra=len(questions),can_delete=False)
question_formset = formset(prefix=FS_PREFIX, initial=questions)
question_only = Question.objects.all().order_by('ordering')
context = {
'question_formset': question_formset,
'question_only': question_only
}
result = context
return result
student.views
from declaration.views import checklist
def create_declaration(request):
the_checklist = checklist(request)
if the_checklist == 'true':
print(the_checklist)
return redirect('student:index')
else:
print(the_checklist)
return render(request, 'student/declaration/declaration-form.html', the_checklist)
шаблон
<div class="row m-0 p-0 mb-2">
<div class="col-lg-12">
<div class="pb-2">
{{ question_formset.management_form|crispy }}
{% crispy question_formset %}
</div>
</div>
</div>
Спасибо за помощь, мы высоко ценим ваши отзывы. Если вы можете сделать выпадающее меню select в виде текста или метки, было бы здорово. Еще раз спасибо