Search code examples
htmldjangoinputlimitrestriction

Limit characters user can enter in input in django view OR html?


I had various occasions where I wanted to but couldn’t limit characters user types in html input. For example what would I do if I would only want numbers and letters? No other like £-“<#>{[. And what would I do if I would want them to only enter uppercase letters? Thanks for help:)


Solution

  • There's a couple of ways you can do this, through Django Form validation, HTML attributes or Javascript.

    Django Validation + HTML attributes

    class TheForm(forms.ModelForm):
        class Meta:
            model = ModuleChoice
            fields = (
                'text',
                )
    
        def __init__(self,  *args, **kwargs):
            super(TheForm, self).__init__(*args, **kwargs)
    
            # HTML attributes:
                # Max Length, user physically couldn't type more than 35
                # some fields also can have the `pattern` attribute which allows you to have REGEX
            self.fields['text'].widget.attrs={'class': 'form-control', 'maxlength': '35'}
    
    
        def is_valid(self):
            valid = super(TheForm, self).is_valid()
            if not self.cleaned_data.get('text'):
                self.add_error('text', 'text needs a Value')
                valid = False
    
            invalidChars = [ '£', '-', '“', '<', '#', '>', '{', '[' ]
            if any([c in self.cleaned_data.get('text') for c in invalidChars]):
                # error ( {field}, {msg} )
                self.add_error('text', 'These £-“<#>{[ characters are Illegal.')
                valid = False
    
            if self.cleaned_data.get('text').islower():
                self.add_error('text', 'All Letters Must be all Upper Case.')
                valid = False
    
            # you could also do Regex:
            import re
            if re.findall('^Nealium.*Uncool$', self.cleaned_data.get('text')):
                self.add_error('text', 'You cannot say Nealium is Uncool.')
                valid = False
    
            # the sky is the limit..
            if The.objects.filter(text=self.cleaned_data.get('text')).count():
                self.add_error('text', 'Duplicate Text.')
                valid = False
    
            return valid
    

    you would then put, below, in your template and if you re-render the page with the invalid form it'll show them.

    {% if form.errors %}{{form.errors}}{% endif %}
    

    Or you can use, below, so access your errors in the template

    print(form.errors)
    print(form.errors.as_data())
    

    Doing it through Javascript is very Similar to the is_valid() in Django Forms, you'd just override the default form.save event and add a few if statements above submitting it


    Edit

    Yes, you could do it in the View- Specifically in the POST:

    def theview(request):
        if request.method == 'POST'
            valid = True
            text = request.POST.get('text')
    
            invalidChars = [ '£', '-', '“', '<', '#', '>', '{', '[' ]
            if any([c in text for c in invalidChars]):
                msg = 'These £-“<#>{[ characters are Illegal.'
                valid = False
    
            # other validation
    
            if valid:
                The.object.create(text=text)
                render(request, 'success.html')
            # not valid
    

    Or you could do it in the Template if you're manually rendering the Form fields

    <form method="post">
        <input id="id_text" name="text" maxlength="35"/>
        <submit>Submit</submit>
    </form>
    

    but if you are rendering your forms in the Template like:

    <form method="post">
        {% csrf_token %}
        {{ form }}
        <input type="submit" value="Submit">
    </form>
    

    or:

    <form method="post">
        {% csrf_token %}
        {{ form.text }}
        <input type="submit" value="Submit">
    </form>
    

    and your View looks like:

    def theview(request):
        form = TheForm()
    
        if request.method == 'POST'
            form = TheForm(request.POST)
            if form.is_valid():
                form.save()
    
                render(request, 'success.html')
          
        data = {
            'form': form,
        }
        return render(request, 'form.html', data)
    

    You might as well do it through the Form object (which was the 1st example)