Convert all CharField Form Field inputs to lowercase in Django forms

django form fields
django uppercase
django uppercase model field
django model charfield lowercase
django models
django model save

I am using a Django form for user signup, where the user is able to enter a coupon code. I want all characters entered in the coupon code field to be converted to lowercase. I've tried using .lower() in the save method, in a custom cleaning method, and in a custom validator, but am having no luck with those approaches. Below is my code.

class StripeSubscriptionSignupForm(forms.Form):
    coupon = forms.CharField(max_length=30,
        required=False,
        validators=[validate_coupon],
        label=mark_safe("<p class='signup_label'>Promo Code</p>")

    def save(self, user):
        try:
            customer, created = Customer.get_or_create(user)
            customer.update_card(self.cleaned_data["stripe_token"])
            customer.subscribe(self.cleaned_data["plan"], self.cleaned_data["coupon"].lower())
        except stripe.StripeError as e:
            # handle error here
            raise e

As mentioned above, I've also tried a cleaning method, but this doesn't work either:

def clean_coupon(self):
    return self.cleaned_data['coupon'].lower()

The solution is to create a custom form field, which allows you to override the to_python method, in which the raw values from the form fields can then be modified.

class CouponField(forms.CharField):
    def to_python(self, value):
        return value.lower()


class StripeSubscriptionSignupForm(forms.Form):
    coupon = CouponField(max_length=30,
        required=False,
        validators=[validate_coupon],
        label=mark_safe("<p class='signup_label'>Promo Code</p>")
    )

Django model - set default charfield in lowercase, Just do it in the save method. ie, override the save method of Model class. def save(self, *args, **kwargs): self.username  CharField in Django Forms is a string field, for small- to large-sized strings. It is used for taking text inputs from the user. The default widget for this input is TextInput. It uses MaxLengthValidator and MinLengthValidator if max_length and min_length are provided. Otherwise, all inputs are valid. CharField has following optional arguments:

Try using a css text-transform with widget in your form like this:

class StripeSubscriptionSignupForm(forms.Form):
    coupon = forms.CharField(max_length=30,
        required=False,
        validators=[validate_coupon],
        label=mark_safe("<p class='signup_label'>Promo Code</p>")
        widget=TextInput(attrs={'style': 'text-transform:lowercase;'})
        )

Form fields | Django documentation, I don't want to change a form, I want all the lowercase logic contained inside the fields in admin, and now I can even create such objects; text input is created for within: monkey_patch/__init__.py from django.forms.fields import CharField  We implemented a LowerCaseCharField. We would be happy to hear better implementation suggestions. from django.db.models.fields import CharField class LowerCaseCharField(CharField): """ De

I came across this problem myself when working on ensuring that the email field in the user model was only saved as lowercase.

The issue for me and I believe for the OP above is that the cleaned values are now indeed in lower case, however the HTML page (the one rendered after the validation and cleaning) shows the pre-cleaned value (i.e. still in uppercase), thus perhaps confusing the user. What is happening is that the the form field value is still as per initial data i.e. X@Y.com and the cleaned data is actually x@y.com .

After processing the submitted form:

>>>user_form.cleaned_data['email']
'x@y.com'

and

>>>user_form['email'].value()
'X@Y.com'

The template uses the user_form['email'].value() instead of the value provided by user_form.cleaned_data['email'], so the user thinks his email has been saved in the uppercase form whereas really it has been saved in lowercase.

In such cases, the simplest way to present the user_form back to the client with the cleaned fields appearing in the template is to just reload the saved form directly after saving. As per the following two examples (one saving to the database one not saving to the database).

forms.py

from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
    """
    UserForm is a simple form to allow a user to change his/her name and email.
    """
    class Meta:
        model = User 
        fields = ['first_name', 'last_name', 'email']

    def clean_email(self):
        """
        ensure that email is always lower case.
        """
        return self.cleaned_data['email'].lower()

in views.py

def post(self, request):
    user_form = UserForm(request.POST, instance=request.user)
    if user_form.is_valid():
        user_form.save()  # using the provided save from Modelform in this case
        user_form = UserForm(instance=request.user)  # reload the amended user data
    return render(request, 'myApp/user_details.html',{'user_form': user_form})

The key line here is in views.py,the user_form = UserForm(instance=request.user), where the form is reloaded. The effect here is to repopulate the form with the cleaned, (and in this case saved) data before it is presented to the user. Now you can change every charfield in the form to lowercase by having the appropriate clean_fieldname call for those fields.

Note: if you are not interacting with a database (or just don´t wish to reload from the database) you can repopulate the form as follows:

def post(self, request):
    user_form = UserForm(request.POST) #gather the post'ed data
    if user_form.is_valid():
        user_form.process()  # process the gathered cleaned data            
        user_form = UserForm(
            {'email': user_form.cleaned_data['email'],
            'first_name': user_form.cleaned_data['first_name'],
            'last_name': user_form.cleaned_data['last_name'],}
        ) # reload the form       
    return render(request, 'myApp/user_details.html',{'user_form': user_form})

As a slight optimization here, you can use the built in check :

 if user_form.has_changed():

following on from the is_valid() check (or in conjunction with it) -usually there is no need to save or process a form if nothing has changed on the form.

How do you make a lowercase field in a django model?, python - Convert all CharField Form Field inputs to lowercase in Django forms - i using django form user signup, user able enter coupon code. want characters  A widget is Django’s representation of an HTML input element. The widget handles the rendering of the HTML, and the extraction of data from a GET/POST dictionary that corresponds to the widget. Whenever you specify a field on a form, Django will use a default widget that is appropriate to the type of data that is to be displayed.

python, Django form field types, generated HTML, default widget and validation forms.​GenericIPAddressField(). <input type="text" > forms.widgets.TextInput(). Works just like CharField, but server-side Django validates the (text) value can be converted In Django a 'slug' is a value that contains only lower case letters, numbers,  As explained in “Outputting forms as HTML” above, the default label for a Field is generated from the field name by converting all underscores to spaces and upper-casing the first letter. Specify label if that default behavior doesn’t result in an adequate label.

Django form field types: Widgets, options and validations, Python code examples for the forms module in the Django open source project. forms is a module within the Django project for safely handling user input in a web for field_entry in kwargs["instance"].fields.all(): field_entries[field_entry.​field_id] CharField(label=" ", required=False) self.fields["%s_filter" % field_key]​  Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Learn more . How to make a form field numeric only in Django. Ask Question Asked 6 years, 8 months ago. Active 2 years, 6 months ago. Viewed 19k

django.forms Example Code, To convert string to lower case replace upper() for lower() CharField(​max_length=60, blank=True, null=True) email = models. ChoiceField in Django Forms is a string field, for selecting a particular choice out of a list of available choices. It is used to implement State, Countries etc. like fields for which information is already defined and user has to choose one. It is used for taking text inputs from the user.

Comments
  • Actually, forms.Form doesn't have any method called save. So use ModelForm instead or save coupon in the views.
  • @ruddra: are you sure forms.form dont have save method?
  • I am. You can check yourself at Django source code.
  • @ruddra... Interesting, but the rest of the save method is working in my StripeSubscriptionSignupForm class (other than the .lower() code).
  • I checked, save should work, as you created this method, and not override anything.
  • Shouldn't the to_python override do return self.super().to_python(value).lower() rather than return value.lower()? Aren't we skipping validations like that?
  • Also, forms.CharField doesn't seem to exist, shouldn't that be models.CharField?
  • @SebastiánVansteenkiste see here: docs.djangoproject.com/en/2.2/ref/forms/widgets/…
  • This is a clever approach. However, I'd prefer the fields to be able to display uppercase characters, which are converted to lowercase after form submission. Also, I believe the widget code needs to be: widget=forms.TextInput(attrs={'style': 'text-transform:lowercase;'}
  • cool way to encourage a certain style and prevent frustration of errors ever happening