2

I am using Django Userena for the first time.So can not able to customize the appearance of the change password form,as we know that userena used the default change password form from django.contrib.auth.forms (if i am not wrong).Now this is becoming tough for me to customize the appearance of the change password form template cause in the change password template, each and every field is rendered as {{ form.as_p }} like that

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

in mention,i have already been able to format the appearance of other forms provided by userena.for example i have changed the appearance of the Edit Profile form by adding css classes in the forms.py like that

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)

and worked, change password form has been rendered from django.contrib.auth.forms,so i don't know how to add css classes in each field of that that file as it is a core file of Django.May be there alternative way to do this ,but i am inexperience in django and also the django userena,i don't know how do this.

Md. Tanvir Raihan
  • 4,075
  • 9
  • 37
  • 70
  • 1
    You can see the id or the class by inspecting element or viewing the page source. And then add styling to it in the css. – Kakar Jan 17 '15 at 07:51

3 Answers3

2

It's too late, but for the new visitors, you can create a new form in your forms.py as

# 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 

and in your views.py you could use PasswordChangeView with your form as

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

That's all.

Ali Aref
  • 1,893
  • 12
  • 31
1

You actually need to override the userena view altogether because it passes its own form in the view

urls.py:

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

In your 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)

And finally

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)

do even more customization on the html template

 <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>
Dr Manhattan
  • 13,537
  • 6
  • 45
  • 41
1

If you are going to use Bootstrap and jQuery you can also customize all templates in your userena base file with jQuery.

In my case it saved me a lot of messy code in multiple files across the project.

Just change the desired parts with jQuery or pure JS and CSS for example:

$( "input" ).addClass( "form-control" );
sharpshadow
  • 1,256
  • 1
  • 9
  • 9