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:)
CodePudding user response:
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)