8👍
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>")
)
7👍
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;'})
)
- [Django]-Django clean-up code
- [Django]-Django: How to remove bullet point when printing form errors
- [Django]-Virtualenv, sys.path and site-packages
- [Django]-Django modelfield, how do I get the actual value?
- [Django]-How to store HDF5 (HDF Store) in a Django model field
1👍
I came across this problem myself when working on ensuring that the email field in the user model was only saved as lowercase. The advantage to the method I outline below is that you can control the formating of each field in the form – as against the selected answer above, which will convert all fields to lowercase regardless of whether you wish so or not.
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), which would confuse 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.
- [Django]-Django aggregation across multiple tables in ModelAdmin queryset
- [Django]-Sphinx search in django admin
- [Django]-Create Docker container with Django, npm and gulp
- [Django]-Django clean-up code
- [Django]-Testing Django project, how can I avoid Errno 10054?