Django-Registration: Overriding the default fields

孤街醉人 提交于 2019-12-11 06:49:15

问题


Yesterday I faced a problem trying to override the RegistrationForm of Django-Registration app. The class RegistrationForm inherit from UserCreationForm of Django, which is based on ModelForm, so I created my custom class inheriting from RegistrationForm in this way:

from django import forms
from django.contrib.auth.models import User

class MyRegistrationForm(RegistrationForm):
    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')
        widgets = {
            'username': forms.TextInput(
                attrs={'placeholder': 'hasdsa', 'class': 'form-control'}),
            'email': forms.EmailInput(
                attrs={'placeholder': 'hasdsa', 'class': 'form-control'}),
            'password1': forms.PasswordInput(
                attrs={'placeholder': 'hasdsa', 'class': 'form-control'}),
            'password2': forms.PasswordInput(
                attrs={'placeholder': 'hasdsa', 'class': 'form-control'}),
        }

I set the Meta class in this way because the model User and the fields username, email, password1, password2 are the same attribute of UserCreationForm. This code live in a module named accounts / forms.py and is called directly from accounts / urls.py in this way:

from django.conf.urls import include, url

from registration.backends.hmac import views

from accounts.forms import MyRegistrationForm

urlpatterns = [
    url(r'^register/$', views.RegistrationView.as_view(form_class=MyRegistrationForm), name='registration_register'),
    url(r'', include('registration.backends.hmac.urls')),
]

The goal here is overriding the attributes of an input field of a form with widgets adding attributes like class or placeholder or change the labels of the form or adding error_messages and so on.

As explained in Django-Registration docs to achieve this you just need to pass your custom form to form_class parameter of the RegistrationView. Done. It doesn't works and I don't know why.

As you see in the screenshot, DDT (Django Debug Toolbar) reports the fields of the form and all data available from there. The output of {{ form.as_p }} tag return this result:

<form method="post" action=".">
    <input type='hidden' name='csrfmiddlewaretoken' value='dNeT0R1JPIBtsrGCbcyPQjPLDAW7P7qb' />
    <p><label for="id_username">Username:</label> <input class="form-control" id="id_username" maxlength="30" name="username" placeholder="hasdsa" type="text" /> <span class="helptext">Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only.</span></p>
    <p><label for="id_email">Email:</label> <input id="id_email" name="email" type="email" /> <span class="helptext">email address</span></p>
    <p><label for="id_password1">Password:</label> <input id="id_password1" name="password1" type="password" /></p>
    <p><label for="id_password2">Password confirmation:</label> <input id="id_password2" name="password2" type="password" /> <span class="helptext">Enter the same password as before, for verification.</span></p>
    <input type="submit" value="Submit" />
</form>

And the bug come from there. As you can see, only the username field is changed. You can see the attribute class and placeholder overrided in the widget. But all other fields are still the same. Just a question: Why?

Instead to set the model and fields attributes of the meta class in the way reported above, I tried with:

class MyRegistrationForm(RegistrationForm):
    class Meta(RegistrationForm.Meta):
        widgets = { ... }

We don't need to change those attributes, we are only interested on widgets, but the result is the same, it doesn't works.

I'd also like to know what is the best way to change the widgets of all forms in a project. Overriding each form in this way? Using a template tag and filter each form field? Using a middleware? If you use a framework like bootstrap, probably you want to have the attribute class="form-control" for each input field. What is the best way to achieve this?

Thanks for your time and support.


回答1:


Try like this:

class SignUpForm(UserCreationForm):
    username = forms.Field(widget=forms.TextInput(attrs={'class':'form-control'}))
    email = forms.Field(widget=forms.EmailInput(attrs={'class':'form-control'}))
    password1 = forms.Field(widget=forms.PasswordInput(attrs={'class':'form-control'}))
    password2 = forms.Field(widget=forms.PasswordInput(attrs={'class':'form-control'}))

class Meta:
    model = User    
    fields = ('username','email','password1',)  

Works for me



来源:https://stackoverflow.com/questions/41088567/django-registration-overriding-the-default-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!