How to remove 'This field is required' error from required field of ModelForm in django

Hi there,

I have a ModelForm which has required fields. I want to remove the required error from the field that stays on top of the field if we have left it empty, like below:
image

My forms.py is:

class InviteUserByAdminForm(forms.ModelForm):
    class Meta:
        model = Invitation
        fields = (
            "invitee_first_name",
            "invitee_last_name",
            "sent_to",
        )

I tried adding this in the Meta class:

error_messages = {
            'sent_to': {
                'required': _("")
            },
}

It removes the error but the bullet point stays there.

Can anyone helps me how to remove the whole error totally forever?

1 Like

I had a similar issue and this error was gone when I defined a widget for the form elements within the meta class, so you could try this:

class InviteUserByAdminForm(forms.ModelForm):
    class Meta:
        model = Invitation
        fields = (
            "invitee_first_name",
            "invitee_last_name",
            "sent_to",
        )

	    widgets = {
            "sent_to" : forms.TextInput(attrs={'class':'form-control', 'placeholder':""}),
        }

if that doesn’t work, use blank=True argument in your CharField model

I am getting this error:

TypeError: Field.__init__() got an unexpected keyword argument 'attrs'

full error details are:

Traceback (most recent call last):
  File "C:\Users\khubi\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1016, in _bootstrap_inner
    self.run()
  File "C:\Users\khubi\AppData\Local\Programs\Python\Python310\lib\threading.py", line 953, in run
    self._target(*self._args, **self._kwargs)
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\core\management\commands\runserver.py", line 134, in inner_run
    self.check(display_num_errors=True)
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\core\management\base.py", line 487, in check
    all_issues = checks.run_checks(
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\core\checks\registry.py", line 88, in run_checks
    new_errors = check(app_configs=app_configs, databases=databases)
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\core\checks\urls.py", line 42, in check_url_namespaces_unique
    all_namespaces = _load_all_namespaces(resolver)
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\core\checks\urls.py", line 61, in _load_all_namespaces     
    url_patterns = getattr(resolver, "url_patterns", [])
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\utils\functional.py", line 49, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\urls\resolvers.py", line 696, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\utils\functional.py", line 49, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\urls\resolvers.py", line 689, in urlconf_module
    return import_module(self.urlconf_name)
  File "C:\Users\khubi\AppData\Local\Programs\Python\Python310\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "D:\Projects\meistery\projects\pricing_password_management_poc\inviteandresetpass\inviteandresetpass\urls.py", line 19, in <module>    from apps.accounts.views import auth0login
  File "D:\Projects\meistery\projects\pricing_password_management_poc\inviteandresetpass\apps\accounts\views.py", line 30, in <module>    
    from .forms import (
  File "D:\Projects\meistery\projects\pricing_password_management_poc\inviteandresetpass\apps\accounts\forms.py", line 30, in <module>    
    class InviteUserByQAForm(forms.ModelForm):
  File "D:\Projects\meistery\projects\pricing_password_management_poc\inviteandresetpass\apps\accounts\forms.py", line 58, in InviteUserByQAForm
    class Meta:
  File "D:\Projects\meistery\projects\pricing_password_management_poc\inviteandresetpass\apps\accounts\forms.py", line 86, in Meta        
    "sent_to" : forms.CharField(attrs={'class':'form-control', 'placeholder':""}),
  File "D:\Projects\meistery\venvs\inviteandresetpass\lib\site-packages\django\forms\fields.py", line 267, in __init__
    super().__init__(**kwargs)
TypeError: Field.__init__() got an unexpected keyword argument 'attrs'

Also, are you sure that doing this will not change the field’s required status? I wan the field to be required but I just don’t want his message “This field is required.”

I’m using Django 4.1, which version are you using?

You can also modify the initializer in the form

class InviteUserByAdminForm(forms.ModelForm):    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['sent_to'].required = True

I’m not sure why you’re getting this widget error, it is tabbed properly in the Meta class? make sure you leave the comma at the end of the widget line if there are more than one widgets being used.

I was getting that exact error message on an image upload field (ImageField), when I changed my widget to be in the Meta class, the error was gone. It is commented out how I was previously defining the image form field (and was causing that error).

“CustomImageField” is just a forms.ImageField …I was initially trying to override the validation, none of those efforts got me anywhere

@Spha this is what my full class looks like:

class InviteUserByQAForm(forms.ModelForm):
    workspaces = forms.ChoiceField(
        label="Workspaces (required)",
        widget=forms.RadioSelect,
        choices=workspaces_choices
    )
    make_workspace_admin = forms.BooleanField(required=False, label="Make Workspace Admin (optional)")
    expiry_time = forms.IntegerField(
        label="Expiry Time in seconds (optional)",
        required=False,
        help_text="Enter time in seconds. For example, enter \
            3600 for 1 hour and 93600 for 1 day and 2 hours etc."
    )

    class Meta:
        model = Invitation
        fields = (
            "invitee_first_name",
            "invitee_last_name",
            "sent_to",
        )
        error_messages = {
            'sent_to': {
                'invalid': _("Enter a valid email."),
            },
        }
        labels = {
            'invitee_first_name': _('Invitee First Name (optional)'),
            'invitee_last_name': _('Invitee Last Name (optional)'),
            'sent_to': _('Invitee Email (required)'),
        }
        widgets = {
            "sent_to" : forms.CharField(attrs={'class':'form-control', 'placeholder':""}),
        }

I am still getting the same error and I am using Django 4.0.5.

It should be forms.TextInput, definitely not forms.CharField - this will cause problems.

Check here:

https://docs.djangoproject.com/en/4.1/ref/forms/widgets/#built-in-widgets

@Spha OK I put this:

widgets = {
            "sent_to" : forms.TextInput(attrs={'class':'form-control', 'placeholder':""}),
        }

Now my code runs fine but I still see that message “This field is required”

Is there some database model in models.py which links to that field? If you were using a charfield, the default case is that all fields are required (blank = False by default). Can you copy and paste the model from models.py?

@Spha yes there is database model which links to the sent_to field in the ModelForm. Below is that database model:

class Invitation(models.Model):
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    expiration_date = models.DateTimeField(null=True, blank=True)
    invitee_first_name = models.CharField(
        max_length=254,
        null=True,
        blank=True,
        verbose_name="Invitee First Name"
    )
    invitee_last_name = models.CharField(
        max_length=254,
        null=True,
        blank=True,
        verbose_name="Invitee Last Name"
    )
    sent_to = models.EmailField(
        max_length=254,
        verbose_name="Invitee Email"
    )
    secret = models.UUIDField(default=uuid.uuid4, unique=True)
    accepted_at = models.DateTimeField(null=True, blank=True)
    is_canceled = models.BooleanField(default=False)
    invited_to = models.CharField(
        max_length=254,
        null=True,
        blank=True,
        verbose_name="Workspace Invited To"
    )

because I see now that it’s an email field, it might be better then to change the widget to

 widgets = {
            "sent_to" : forms.EmailInput(attrs={'class':'form-control', 'placeholder':""}),
        }

This might not be the solution to the problem however.

In models.py, what happens if you change it to this?:

  sent_to = models.EmailField(
        max_length=254,
        blank = True,
        verbose_name="Invitee Email"
    )

Does the “required” message still show?

If you will change that remember you need to run:

python manage.py makemigrations
python manage.py migrate

This did nothing

But doing it removed the message

But the issue is that now the Email field is not required, I mean if I leave the email field blank, the form gets submitted.

The widget would work instead of “blank = True” in the case that you had a model with those fields that were separate from your main model (a separate model linking to the main model with a foreign key), but you have one model holding all fields so the widget declaration is not important in this case.

So you say this field is required, but in your first post you try to submit it empty. How is this validator message a problem then? Is it that you wanted to alter the validation message?

@Spha yes I want the field to be required, just want to get rid of message, if you see the image I posted I have written (required) in the label so that user would know from there. I just want to remove the message (or you may say alter the message to be empty) and keep the field as required.

@Spha is there any way to show this message only when user leave the field empty and click on submit button?

In that case you can try to make a custom validator. I think I found where this message originates from. It’s in the Field class.

image

image

You could possibly hack this, or override one of the methods. I’m just not sure how best to go about that.

This is what happens for me. It appears that there is some kind of bug, the message shouldn’t stay there the whole time. Sometimes it’s not unwise to close Visual Studio, and open it again…it’s not normal if the message hangs there.

@Spha I ended up achieving my desired behaviour by doing the following:

Keep the required=True flag in the Model’s field. Then on the front end while accessing form, instead of putting whole form like form.as_p, I looped through the form and for each item in the form I put only item.label, item, and item.help_text, I did not write item.errors. This way, now I can have the field as required but I no longer see that message.

For convenience, the above explanation of code looks like below:

<form method="POST">
        {% csrf_token %}
        {% for item in form %}
            <div class="fieldWrapper">
                {{ item.label }} {{ item }}
                {% if item.help_text %}
                    {{ item.help_text|safe }}
                {% endif %}
            </div>
            <br>
        {% endfor %}
        <button type="submit">Invite</button>
    </form>

https://docs.djangoproject.com/en/4.1/ref/models/instances/#validating-objects

this page of the documentation might also be of interest in regard to this

@khaw235 After trying out many things i did find a way…in your views.py for the defined function you must have a context where you have something like context = {“form”: form} instead just write context = {“form”:InviteUserByAdminForm()}
it’ll solve ur problem guarenteed

If that worked for you, then you had something else wrong.

If form = InviteUserByAdminForm(), then the two versions of code you’re showing are identical - other than the syntax error in your second version.

(You may also notice that this topic was marked as solved, indicating that the OP did figure out a solution to the issue they were facing.)

1 Like