简体   繁体   English

将所有 CharField 表单字段输入转换为 Django 表单中的小写

[英]Convert all CharField Form Field inputs to lowercase in Django forms

I am using a Django form for user signup, where the user is able to enter a coupon code.我正在使用 Django 表单进行用户注册,用户可以在其中输入优惠券代码。 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.我已经尝试在 save 方法、自定义清理方法和自定义验证器中使用 .lower() ,但我对这些方法没有运气。 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()

Try using a css text-transform with widget in your form like this:尝试在表单中使用带有小部件的 css 文本转换,如下所示:

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;'})
        )

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.解决方案是创建一个自定义表单字段,它允许您覆盖 to_python 方法,然后可以修改表单字段中的原始值。

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>")
    )

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 (ie still in uppercase), which would confuse the user.对我来说,我相信上面的 OP 的问题是,清理后的值现在确实是小写的,但是 HTML 页面(验证和清理后呈现的页面)显示了预清理的值(即仍然是大写),这会让用户感到困惑。 What is happening is that the the form field value is still as per initial data ie X@Y.com and the cleaned data is actually x@y.com .发生的事情是表单字段值仍然是初始数据,即 X@Y.com 并且清理后的数据实际上是 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.该模板使用 user_form['email'].value() 而不是 user_form.cleaned_data['email'] 提供的值,因此用户认为他的电子邮件已保存为大写形式,而实际上它已保存为小写形式.

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.在这种情况下,将 user_form 返回给客户端的最简单方法是在保存后直接重新加载保存的表单。 As per the following two examples (one saving to the database one not saving to the database).按照以下两个示例(一个保存到数据库,一个不保存到数据库)。

forms.py表格.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在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.这里的关键行是在views.py中,user_form = UserForm(instance=request.user),这里重新加载了表单。 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.现在,您可以通过对这些字段进行适当的 clean_fieldname 调用,将表单中的每个字符字段更改为小写。

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.继 is_valid() 检查(或与其结合)之后 - 通常,如果表单上没有任何更改,则无需保存或处理表单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM