0

I have multiple forms of the same base class like this:

class DatabaseForm(forms.Form):
    active = forms.BooleanField(required=False)  # Determines, if username and password is required
    username = forms.CharField(label="Username", required=False)
    password = forms.CharField(label="Password", required=False)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['active'].label = self.label

    def clean(self):
        cleaned_data = super(DatabaseForm, self).clean()
        active = cleaned_data.get("ative")
        username = cleaned_data.get("username")
        password = cleaned_data.get("password")
        if active and not (username and password):
            raise forms.ValidationError("Please fill in the required database configuration")

        return cleaned_data


class MySQLForm(DatabaseForm):
    label = "MySQL"


class PostgreSQLForm(DatabaseForm):
    label = "PostgreSQL"


class SqliteForm(DatabaseForm):
    label = "Sqlite3"

So only if the user chooses a database, he must fill in the username and password for it.

In my template, the form looks like this:

<form action="." method="post">
    {% csrf_token %}
    {{ mysql_form }}
    {{ postgres_form }}
    {{ sqlite_form }}
    <a id="database-submit-btn" href="#submit"
    class="btn btn-success submit-button">Submit</a>
</form>

Problem: When the user chooses a database by selecting the 'active' field, the 'active' fields of the other databases get set to True. It seems like I can't distinguish between the multiple fields, as they have the same key in the POST request (but I'm not sure that's the whole problem): 'username': ['mysql test', 'postgres test', 'sqlite test'], 'password': ['mysql password', 'postgres password', 'sqlite password']

How can I get this to work and keep the code extendable?

1 Answer 1

1

You can pass the prefix argument when you initialise your forms, this gives each field name a prefix and allows you to have multiple forms with the same field names

def foo(request):
    if request.method == 'POST':
        mysql_form = MySQLForm(request.POST, prefix='mysql')
        postgres_form = PostgreSQLForm(request.POST, prefix='postgres')
        sqlite_form = SqliteForm(request.POST, prefix='sqlite')
    else:
        mysql_form = MySQLForm(prefix='mysql')
        postgres_form = PostgreSQLForm(prefix='postgres')
        sqlite_form = SqliteForm(prefix='sqlite')

Or you can hardcode a prefix for each form in the class itself

class MySQLForm(DatabaseForm):
    label = "MySQL"
    prefix = "mysql"


class PostgreSQLForm(DatabaseForm):
    label = "PostgreSQL"
    prefix = "postgresql"


class SqliteForm(DatabaseForm):
    label = "Sqlite3"
    prefix = "sqlite3"
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.