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

时间:2014-06-19 17:51:18

标签: python django python-2.7

我正在使用Django表单进行用户注册,用户可以在其中输入优惠券代码。我希望在优惠券代码字段中输入的所有字符都转换为小写。我尝试在save方法,自定义清理方法和自定义验证器中使用.lower(),但我对这些方法没有运气。以下是我的代码。

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

如上所述,我也尝试过一种清洁方法,但这也不起作用:

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

3 个答案:

答案 0 :(得分:7)

解决方案是创建一个自定义表单字段,它允许您覆盖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>")
    )

答案 1 :(得分:5)

尝试在表单中使用带有窗口小部件的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;'})
        )

答案 2 :(得分:1)

我在确保用户模型中的电子邮件字段仅保存为小写字母时遇到了这个问题。

对我和我来说,上面的OP的问题是,清除的值现在确实是小写的,但是HTML页面(在验证和清除后呈现的页面)显示了预先清除的值(即仍在大写),因此可能会使用户感到困惑。发生的情况是,表单字段值仍然按照初始数据(即X@Y.com)而已清除,数据实际上是x@y.com。

处理提交的表单后:

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

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

该模板使用user_form ['email']。value()而不是user_form.cleaned_data ['email']提供的值,因此用户认为他的电子邮件已以大写形式保存,但实际上已经保存为小写。

在这种情况下,将出现在模板中的已清理字段显示给用户_form的最简单方法是在保存后直接重新加载保存的表单。按照以下两个示例(一个保存到数据库,一个不保存到数据库)。

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

在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})

此处的关键行在views.py,user_form = UserForm(instance = request.user)中,在此重新加载表单。这样做的作用是在将表单显示给用户之前,用已清理(在这种情况下为已保存)的数据重新填充表单。 现在,您可以通过对这些字段进行适当的clean_fieldname调用,将表单中的每个字符字段更改为小写。

注意:如果您不与数据库进行交互(或者只是不想从数据库中重新加载),则可以按以下方式重新填充表单:

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

这里有一个小的优化,您可以使用内置的check:

 if user_form.has_changed():

遵循is_valid()检查(或与之结合使用)-通常,如果表单上没有任何更改,则无需保存或处理表单。