Edit form fields in Django to modify the input object

2

I need to validate a form, but Foundation Abide PlugIn works by selecting the input fields that have the required tag added:

<input type="text" placeholder="1234" aria-describedby="exampleHelpText" required pattern="number">

As you can see, Django does not print the input fields with additional labels on the screen, it prints the name, type and id, but does not add the tag required at the end.

I have two forms, the basic one generated by WagtailCMS, and one that I have:

class AffiliationInlineForm(forms.ModelForm):
    class Meta:
        model = Affiliation
        fields = ['person', 'affiliation', ]


class AffiliatesForm(forms.ModelForm):
    class Meta:
        model = Affiliates
        fields = '__all__'

I do not add anything here and manually print each field of the form in this way:

{% for field in form %}
            <div class="row">
                <div class="small-12 medium-3 columns">
                    <label for="middle-label id_{{ field.name }}" class="text-right middle">
                        {% if field.field.required %}<span class="required">{{ field.label }}</span>
                        {% else %}
                            {{ field.label }}
                        {% endif %}
                    </label>
                </div>
                <div class="small-12 medium-9 columns">
                    {{ field }}
                    {% if field.help_text %}
                    <label for="id_{{ field.name }}_helptext" class="help-text">{{ field.help_text }}</label>
                    {% endif %}
                </div>
            </div>
        {% endfor %}

How can the field be edited to include this tag and thus validate the form correctly?

Update: I have achieved that the input tag has the required attribute, but I want to condition the label to all the fields that can not be null, as the admin does, is it possible to do this, for example, with a conditional?

And second, in the current form does not recognize that {% form.field.required %} is true, so do not add the * to the end of the label label , which may be happening?

Update: I have managed to add the attribute required to the object input dynamically obtaining the required fields with python in the following way:

def __init__(self, *args, **kwargs):
        super(AffiliatesForm, self).__init__(*args, **kwargs)
        model_fields = self.Meta.model._meta.get_fields()
        model_fields_names = []
        for model_field in model_fields:
            if not model_field.null:
                model_fields_names.append(model_field.name)

        x = model_fields_names.index('id')
        model_fields_names.pop(x)

        # model_fields_names = [f.name for f in model_fields]
        # print(model_fields_names)
        for field in model_fields_names:
            self.fields[field].widget.attrs = {
                'required': True
            }

It's a rustic way, not at all elegant, so I'd like to know how to debug it in a better way.

I am still waiting to put the required attribute in the form fields since the template does not find that it is true field.required , so it does not add the * .

Update: Perfect, everything solved.

It turns out that when verifying if the field was required, it is necessary to put field in the template:

{% if form.position.field.required %}
    
asked by SalahAdDin 15.02.2016 в 02:11
source

1 answer

2

This is very simple to achieve, you just have to overwrite the __init__ of your form and update the attributes of the field.

I'll give you an example using your form AffiliatesForm :

class AffiliatesForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(AffiliatesForm, self).__init__(*args, **kwargs)
        # Agregar el atributo 'required' al campo name
        self.fields['name'].widget.attrs = {
            'required': True
        }

    class Meta:
        model = Affiliates
        fields = [
            'name', 
            # Los demás campos
            '...', 
        ]

In fact, you can add the attributes you want, example with any form:

class MyForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['campo1'].widget.attrs = {
            'required': True
            'placeholder': 'Ejemplo de placeholder'
        }
        self.fields['campo2'].widget.attrs = {
            'required': True
            'data-bar': 'Algo aquí'
        }
        self.fields['campo3'].widget.attrs = {
            'disabled': True,
            'data-foo': 'Algo más por aquí'
        }

    class Meta:
        model = MyModel
        fields = [
            'campo1', 
            'campo2',
            'campo3'
        ]

I, for example, use Bootstrap and I need all my inputs to contain the class form-control , if I have many fields it would be crazy to do it one by one, but you can do something like this:

class MyForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        for field in self.fields:
            self.fields[field].widget.attrs = {
                'class': 'form-control'
            }

    class Meta:
        model = MyModel
        fields = [
            'campo1', 
            '...',
            'campo99999999'
        ]
    
answered by 15.02.2016 / 02:43
source