kopia lustrzana https://github.com/wagtail/wagtail
Allow overriding login form via ``WAGTAILADMIN_USER_LOGIN_FORM`` setting
rodzic
3097e5e610
commit
ef27853a05
|
@ -24,6 +24,7 @@ Changelog
|
||||||
* Added `heading` kwarg to `InlinePanel` to allow heading to be set independently of button label (Adrian Turjak)
|
* Added `heading` kwarg to `InlinePanel` to allow heading to be set independently of button label (Adrian Turjak)
|
||||||
* The value type returned from a `StructBlock` can now be customised (LB (Ben Johnston))
|
* The value type returned from a `StructBlock` can now be customised (LB (Ben Johnston))
|
||||||
* Added `bgcolor` image operation (Karl Hobley)
|
* Added `bgcolor` image operation (Karl Hobley)
|
||||||
|
* Added `WAGTAILADMIN_USER_LOGIN_FORM` setting for overriding the admin login form (Mike Dingjan)
|
||||||
* Fix: Do not remove stopwords when generating slugs from non-ASCII titles, to avoid issues with incorrect word boundaries (Sævar Öfjörð Magnússon)
|
* Fix: Do not remove stopwords when generating slugs from non-ASCII titles, to avoid issues with incorrect word boundaries (Sævar Öfjörð Magnússon)
|
||||||
* Fix: The PostgreSQL search backend now preserves ordering of the `QuerySet` when searching with `order_by_relevance=False` (Bertrand Bordage)
|
* Fix: The PostgreSQL search backend now preserves ordering of the `QuerySet` when searching with `order_by_relevance=False` (Bertrand Bordage)
|
||||||
* Fix: Using `modeladmin_register` as a decorator no longer replaces the decorated class with `None` (Tim Heap)
|
* Fix: Using `modeladmin_register` as a decorator no longer replaces the decorated class with `None` (Tim Heap)
|
||||||
|
|
|
@ -224,6 +224,13 @@ Dashboard
|
||||||
This setting lets you change the number of items shown at 'Your most recent edits' on the dashboard.
|
This setting lets you change the number of items shown at 'Your most recent edits' on the dashboard.
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
WAGTAILADMIN_USER_LOGIN_FORM = 'users.forms.LoginForm'
|
||||||
|
|
||||||
|
Allows the default ``LoginForm`` to be extended with extra fields.
|
||||||
|
|
||||||
|
|
||||||
Images
|
Images
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ Other features
|
||||||
* Added ``heading`` kwarg to ``InlinePanel`` to allow heading to be set independently of button label (Adrian Turjak)
|
* Added ``heading`` kwarg to ``InlinePanel`` to allow heading to be set independently of button label (Adrian Turjak)
|
||||||
* The value type returned from a ``StructBlock`` can now be customised. See :ref:`custom_value_class_for_structblock` (LB (Ben Johnston))
|
* The value type returned from a ``StructBlock`` can now be customised. See :ref:`custom_value_class_for_structblock` (LB (Ben Johnston))
|
||||||
* Added `bgcolor` image operation (Karl Hobley)
|
* Added `bgcolor` image operation (Karl Hobley)
|
||||||
|
* Added ``WAGTAILADMIN_USER_LOGIN_FORM`` setting for overriding the admin login form (Mike Dingjan)
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
|
@ -64,19 +64,24 @@ class EmailLinkChooserForm(forms.Form):
|
||||||
|
|
||||||
class LoginForm(AuthenticationForm):
|
class LoginForm(AuthenticationForm):
|
||||||
username = forms.CharField(
|
username = forms.CharField(
|
||||||
max_length=254,
|
max_length=254, widget=forms.TextInput(attrs={'tabindex': '1'}))
|
||||||
widget=forms.TextInput(attrs={'tabindex': '1'}),
|
|
||||||
)
|
|
||||||
password = forms.CharField(
|
password = forms.CharField(
|
||||||
widget=forms.PasswordInput(attrs={'placeholder': ugettext_lazy("Enter password"),
|
widget=forms.PasswordInput(attrs={
|
||||||
'tabindex': '2',
|
'tabindex': '2',
|
||||||
}),
|
'placeholder': ugettext_lazy("Enter password"),
|
||||||
)
|
}))
|
||||||
|
|
||||||
def __init__(self, request=None, *args, **kwargs):
|
def __init__(self, request=None, *args, **kwargs):
|
||||||
super().__init__(request=request, *args, **kwargs)
|
super().__init__(request=request, *args, **kwargs)
|
||||||
self.fields['username'].widget.attrs['placeholder'] = ugettext_lazy("Enter your %s") \
|
self.fields['username'].widget.attrs['placeholder'] = (
|
||||||
% self.username_field.verbose_name
|
ugettext_lazy("Enter your %s") % self.username_field.verbose_name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def extra_fields(self):
|
||||||
|
for field_name, field in self.fields.items():
|
||||||
|
if field_name not in ['username', 'password']:
|
||||||
|
yield field_name, field
|
||||||
|
|
||||||
|
|
||||||
class PasswordResetForm(PasswordResetForm):
|
class PasswordResetForm(PasswordResetForm):
|
||||||
|
|
|
@ -56,6 +56,18 @@
|
||||||
<p class="help"><a href="{% url 'wagtailadmin_password_reset' %}">{% trans "Forgotten it?" %}</a></p>
|
<p class="help"><a href="{% url 'wagtailadmin_password_reset' %}">{% trans "Forgotten it?" %}</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
{% block extra_fields %}
|
||||||
|
{% for field_name, field in form.extra_fields %}
|
||||||
|
<li class="full">
|
||||||
|
{{ field.label_tag }}
|
||||||
|
<div class="field iconfield">
|
||||||
|
{{ field }}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock extra_fields %}
|
||||||
|
|
||||||
{% comment %}
|
{% comment %}
|
||||||
Removed until functionality exists
|
Removed until functionality exists
|
||||||
<li class="checkbox">
|
<li class="checkbox">
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
from django.forms.fields import CharField
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from wagtail.admin.forms import LoginForm
|
||||||
|
|
||||||
|
|
||||||
|
class CustomLoginForm(LoginForm):
|
||||||
|
captcha = CharField(
|
||||||
|
label='Captcha', help_text="should be in extra_fields()")
|
||||||
|
|
||||||
|
|
||||||
|
class TestLoginForm(TestCase):
|
||||||
|
|
||||||
|
def test_extra_fields(self):
|
||||||
|
form = CustomLoginForm()
|
||||||
|
self.assertEqual(list(form.extra_fields), [
|
||||||
|
('captcha', form.fields['captcha'])
|
||||||
|
])
|
|
@ -17,6 +17,15 @@ from wagtail.admin.utils import get_available_admin_languages
|
||||||
from wagtail.core.models import UserPagePermissionsProxy
|
from wagtail.core.models import UserPagePermissionsProxy
|
||||||
from wagtail.users.forms import NotificationPreferencesForm, PreferredLanguageForm
|
from wagtail.users.forms import NotificationPreferencesForm, PreferredLanguageForm
|
||||||
from wagtail.users.models import UserProfile
|
from wagtail.users.models import UserProfile
|
||||||
|
from wagtail.utils.loading import get_custom_form
|
||||||
|
|
||||||
|
|
||||||
|
def get_user_login_form():
|
||||||
|
form_setting = 'WAGTAILADMIN_USER_LOGIN_FORM'
|
||||||
|
if hasattr(settings, form_setting):
|
||||||
|
return get_custom_form(form_setting)
|
||||||
|
else:
|
||||||
|
return forms.LoginForm
|
||||||
|
|
||||||
|
|
||||||
# Helper functions to check password management settings to enable/disable views as appropriate.
|
# Helper functions to check password management settings to enable/disable views as appropriate.
|
||||||
|
@ -136,7 +145,7 @@ def login(request):
|
||||||
return auth_views.login(
|
return auth_views.login(
|
||||||
request,
|
request,
|
||||||
template_name='wagtailadmin/login.html',
|
template_name='wagtailadmin/login.html',
|
||||||
authentication_form=forms.LoginForm,
|
authentication_form=get_user_login_form(),
|
||||||
extra_context={
|
extra_context={
|
||||||
'show_password_reset': password_reset_enabled(),
|
'show_password_reset': password_reset_enabled(),
|
||||||
'username_field': get_user_model().USERNAME_FIELD,
|
'username_field': get_user_model().USERNAME_FIELD,
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.module_loading import import_string
|
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
from django.views.decorators.vary import vary_on_headers
|
from django.views.decorators.vary import vary_on_headers
|
||||||
|
|
||||||
|
from wagtail.utils.loading import get_custom_form
|
||||||
from wagtail.utils.pagination import paginate
|
from wagtail.utils.pagination import paginate
|
||||||
from wagtail.admin import messages
|
from wagtail.admin import messages
|
||||||
from wagtail.admin.forms import SearchForm
|
from wagtail.admin.forms import SearchForm
|
||||||
|
@ -28,20 +27,10 @@ change_user_perm = "{0}.change_{1}".format(AUTH_USER_APP_LABEL, AUTH_USER_MODEL_
|
||||||
delete_user_perm = "{0}.delete_{1}".format(AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME.lower())
|
delete_user_perm = "{0}.delete_{1}".format(AUTH_USER_APP_LABEL, AUTH_USER_MODEL_NAME.lower())
|
||||||
|
|
||||||
|
|
||||||
def get_custom_user_form(form_setting):
|
|
||||||
try:
|
|
||||||
return import_string(getattr(settings, form_setting))
|
|
||||||
except ImportError:
|
|
||||||
raise ImproperlyConfigured(
|
|
||||||
"%s refers to a form '%s' that is not available" %
|
|
||||||
(form_setting, getattr(settings, form_setting))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_creation_form():
|
def get_user_creation_form():
|
||||||
form_setting = 'WAGTAIL_USER_CREATION_FORM'
|
form_setting = 'WAGTAIL_USER_CREATION_FORM'
|
||||||
if hasattr(settings, form_setting):
|
if hasattr(settings, form_setting):
|
||||||
return get_custom_user_form(form_setting)
|
return get_custom_form(form_setting)
|
||||||
else:
|
else:
|
||||||
return UserCreationForm
|
return UserCreationForm
|
||||||
|
|
||||||
|
@ -49,7 +38,7 @@ def get_user_creation_form():
|
||||||
def get_user_edit_form():
|
def get_user_edit_form():
|
||||||
form_setting = 'WAGTAIL_USER_EDIT_FORM'
|
form_setting = 'WAGTAIL_USER_EDIT_FORM'
|
||||||
if hasattr(settings, form_setting):
|
if hasattr(settings, form_setting):
|
||||||
return get_custom_user_form(form_setting)
|
return get_custom_form(form_setting)
|
||||||
else:
|
else:
|
||||||
return UserEditForm
|
return UserEditForm
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.utils.module_loading import import_string
|
||||||
|
|
||||||
|
|
||||||
|
def get_custom_form(form_setting):
|
||||||
|
"""Return custom form class if defined and available"""
|
||||||
|
try:
|
||||||
|
return import_string(getattr(settings, form_setting))
|
||||||
|
except ImportError:
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
"%s refers to a form '%s' that is not available" %
|
||||||
|
(form_setting, getattr(settings, form_setting))
|
||||||
|
)
|
Ładowanie…
Reference in New Issue