Search code examples
djangoformsmethodology

Django methodology for forms and subforms


This is an open question. I am trying to write HTML pages for defining / editing questions (database objects). A question is composed of a small text and a type: the type indicates its declination. The question declinations are, for example, slider, yes-no, free-text or multiple choice. For the free-text and yes-no declinations, no further information is needed. But for the slider and multiple choice ones, additionnal information have to be entered.

Now what I done / tried is create form, view and template to define a generic question, and create sub forms, views and templates for each question declination that needs additionnal fields.

The problem is that I encounter difficulties to keep the generic question id in the sub forms to attach the additionnal fields to the question. I tried to pass it to the sub view, but I must have access to it in the form too to save the database object with the question reference, so it means adding a hidden input field in the form, which leads to other issues, etc etc...

What I lack is web-development experience... The better thing I could get is dynamic drop-down menus adapting to the selected question type, but I do not know javascript or ajax language for now, so a few different views/templates would be enough.

What would be the easiest / best way to achieve this ? I am not asking for code but rather something like a methodology.

Please let me know if I missed something that makes the question incomprehensible.


Solution

  • Your methodology seems fine to me (creating base view, form class and template that would be inherited and customized for each declination), except for the model part.

    Since your declinations may have some custom fields, I don't think it is efficient to use the same model for all your questions type.

    I would use model inheritance, as follows:

    class BaseQuestion(models.Model):
        """Your base model for all questions"""
        title = models.CharField(max_length=255)
        description = models.TextField()
    
    class YesNoQuestion(BaseQuestion):
        pass
    
    class FreeTextQuestion(BaseQuestion):
        pass
    
    class MultipleChoicesQuestion(BaseQuestion):
        # assuming you have a QuestionChoice model to store your available choices
        choices = models.ManyToManyField(QuestionChoice)
    
    class SliderQuestion(BaseQuestion):
        slider_start = models.IntegerField(default=1)
        slider_end = models.IntegerField(default=10)
    

    Please refer to Django documentation for an in-depth explanation about model-inheritance, but there is one thing you need to know: it will impact performance, especially on large databases. However, in your situation, it seems the way to go.

    Also note that some django applications such as django-polymorphic will probably help you working with model inheritance.

    For the rest of the process, well, I would follow this process:

    • A view that handle the base form for a question (title and description fields), plus an additionnal field with the list of all available question declinations
    • when the user select a type, you fire an ajax request that will post the form data. The view does not save anything but, instead, return another form, corresponding to the selected declination, and filled with previously entered values. This way, you don't care about keeping ID, since a whole new form is returned.
    • on post, this form should trigger another, dedicated view for the declination, that will process the data and save an instance of the corresponding Question model into database