2

我是第一次使用 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 提供的其他表单的外观。例如,我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已经从渲染django.contrib.auth.forms,所以我不知道如何在该文件的每个字段中添加 css 类,因为它是 Django 的核心文件。可能有其他方法可以做到这一点,但我对 django 缺乏经验还有 django userena,我不知道该怎么做。

4

3 回答 3

1

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

网址.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 模板进行更多自定义

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

于 2015-07-22T19:38:06.200 回答
1

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

就我而言,它在整个项目的多个文件中为我节省了很多杂乱的代码。

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

$( "input" ).addClass( "form-control" );
于 2015-08-17T23:32:04.267 回答
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"

就这样。

于 2021-03-03T18:48:48.537 回答