如何自定义Django-Userena更改密码表单的外观

时间:2015-01-17 06:55:40

标签: python django forms django-userena

我第一次使用Django Userena。所以无法自定义更改密码表单的外观,因为我们知道userena使用了django.contrib.auth.forms的默认更改密码表单(如果我没有错的话) )。现在,我很难在change password模板中自定义更改密码表单模板的外观,因此每个字段都呈现为{{ form.as_p }}

<form action = "" method="post" role = "form">
 <fieldset>
    <legend>{% trans "Change Password" %}</legend>
     {% csrf_token %}
     {{ form.as_p }}
 </fieldset>
 <input type="submit" value="{% trans "Change password" %}" class="btn btn-success" />
</form>

提到,我已经能够格式化userena提供的其他表单的外观。例如,我通过在{{1}中添加Edit Profile form类来更改css的外观像那样

forms.py

并且工作,class EditProfileForm(forms.ModelForm): """ Base form used for fields that are always required """ first_name = forms.CharField(label=_(u'First name'), max_length=30, widget=forms.TextInput(attrs={'class' : 'form-control'}), required=False) last_name = forms.CharField(label=_(u'Last name'), max_length=30, widget=forms.TextInput(attrs={'class' : 'form-control'}), required=False) background = forms.CharField(label=(u'Background'), max_length=500, widget=forms.Textarea(attrs={'class' : 'form-control'}), required=True) 已经从change password form呈现,所以我不知道如何在该文件的每个字段中添加css类,因为它是Django的核心文件。可能有替代方法可以做到这一点,但我对django和django userena缺乏经验,我不知道怎么做。

3 个答案:

答案 0 :(得分:1)

您实际上需要完全覆盖userena视图,因为它在视图中传递了自己的表单

urls.py:

# Change password
url(r'^(?P<username>[\@\.\w-]+)/password/$',
   accounts.views.my_own_password_change_view,
   name='userena_password_change'),

在views.py中:

@secure_required
@permission_required_or_403('change_user', (get_user_model(), 'username', 'username'))
def my_own_password_change_view(request, username, template_name='userena/password_form.html',
                    pass_form=YourPasswordChangeForm, success_url=None, extra_context=None):
    """ Change password of user.

    This view is almost a mirror of the view supplied in
    :func:`contrib.auth.views.password_change`, with the minor change that in
    this view we also use the username to change the password. This was needed
    to keep our URLs logical (and REST) across the entire application. And
    that in a later stadium administrators can also change the users password
    through the web application itself.

    :param username:
        String supplying the username of the user who's password is about to be
        changed.

    :param template_name:
        String of the name of the template that is used to display the password
        change form. Defaults to ``userena/password_form.html``.

    :param pass_form:
        Form used to change password. Default is the form supplied by Django
        itself named ``PasswordChangeForm``.

    :param success_url:
        Named URL that is passed onto a :func:`reverse` function with
        ``username`` of the active user. Defaults to the
        ``userena_password_complete`` URL.

    :param extra_context:
        Dictionary of extra variables that are passed on to the template. The
        ``form`` key is always used by the form supplied by ``pass_form``.

    **Context**

    ``form``
        Form used to change the password.

    """
    user = get_object_or_404(get_user_model(),
                             username__iexact=username)

    form = pass_form(user=user)

    if request.method == "POST":
        form = pass_form(user=user, data=request.POST)
        if form.is_valid():
            form.save()

            # Send a signal that the password has changed
            userena_signals.password_complete.send(sender=None,
                                                   user=user)

            if success_url: redirect_to = success_url
            else: redirect_to = reverse('userena_password_change_complete',
                                        kwargs={'username': user.username})
            return redirect(redirect_to)

    if not extra_context: extra_context = dict()
    extra_context['form'] = form
    extra_context['profile'] = get_user_profile(user=user)
    return ExtraContextTemplateView.as_view(template_name=template_name,
                                            extra_context=extra_context)(request)

最后

class YourPasswordChangeForm(forms.ModelForm):
""" Base form used for fields that are always required """
first_name = forms.CharField(label=_(u'First name'),
                             max_length=30,
                             widget=forms.TextInput(attrs={'class' : 'form-control'}),
                             required=False)
last_name = forms.CharField(label=_(u'Last name'),
                            max_length=30,
                            widget=forms.TextInput(attrs={'class' : 'form-control'}),
                            required=False)
background = forms.CharField(label=(u'Background'),
                            max_length=500,
                            widget=forms.Textarea(attrs={'class' : 'form-control'}),
                            required=True)

在html模板上进行更多自定义

&#13;
&#13;
	<form action="" method="post" id="password_change_form">
		{% csrf_token %}
        {% for field in form %}
            <div class="profile-input w33">
                <div class="profile-label" for="{{ field.name }}">{{ field.label }}</div>
                {{ field }}
                {{ field.errors }}
            </div>
        {% endfor %}
        <div class="profile-input w33">
            <input type="submit" class="input updatebtn" value="{% trans "UPDATE" %}"/>
        </div>
	</form>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

如果您打算使用Bootstrap和jQuery,您还可以使用jQuery自定义userena基本文件中的所有模板。

在我的案例中,它在整个项目的多个文件中为我节省了很多混乱的代码。

只需使用jQuery或纯JS和CSS更改所需的部分,例如:

$( "input" ).addClass( "form-control" );

答案 2 :(得分:0)

为时已晚,但对于新访客来说, 您可以在 forms.py 中创建一个新表单

# forms.py
from django.contrib.auth.forms import PasswordChangeForm
...

class MyPasswordChangeForm(PasswordChangeForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["old_password"].widget = forms.PasswordInput(attrs={"class": "form-control"})
        self.fields["new_password1"].widget = forms.PasswordInput(attrs={"class": "form-control"})
        self.fields["new_password2"].widget = forms.PasswordInput(attrs={"class": "form-control"})
        # other customization 

并且在您的 views.py 中,您可以将 PasswordChangeView 与您的表单一起使用

# views.py
...
from django.contrib.auth.views import PasswordChangeView
from .forms import MyPasswordChangeForm

...
class ChangePasswordView(PasswordChangeView):
    form_class = MyPasswordChangeForm
    template_name = "path/to/your/template.html"

仅此而已。