Deprecate user form-related settings

pull/12058/head
Sage Abdullah 2024-07-02 16:23:01 +01:00 zatwierdzone przez Matt Westcott
rodzic 449a48d7f9
commit f126a4860e
6 zmienionych plików z 175 dodań i 11 usunięć

Wyświetl plik

@ -145,7 +145,7 @@ class UserViewSet(WagtailUserViewSet):
```
```{versionchanged} 6.2
Instead of customizing the forms via the [`WAGTAIL_USER_EDIT_FORM`, `WAGTAIL_USER_CREATION_FORM`, and `WAGTAIL_USER_CUSTOM_FIELDS` settings](user_form_settings), we recommend customizing them via the viewset instead, as explained above. The aforementioned settings will be deprecated in a future release.
The [`WAGTAIL_USER_EDIT_FORM`, `WAGTAIL_USER_CREATION_FORM`, and `WAGTAIL_USER_CUSTOM_FIELDS` settings](user_form_settings) have been deprecated in favor of customizing the form classes via `UserViewSet.get_form_class()`.
```
The group forms and views can be customized in a similar way – see [](customizing_group_views).

Wyświetl plik

@ -514,7 +514,9 @@ WAGTAIL_USER_EDIT_FORM = 'users.forms.CustomUserEditForm'
Allows the default `UserEditForm` class to be overridden with a custom form when a custom user model is being used and extra fields are required in the user edit form.
For further information See {doc}`/advanced_topics/customisation/custom_user_models`.
```{versionchanged} 6.2
This setting has been deprecated in favor of customizing the form classes via `UserViewSet.get_form_class()` and will be removed in a future release. For further information, see [](custom_userviewset).
```
### `WAGTAIL_USER_CREATION_FORM`
@ -524,7 +526,9 @@ WAGTAIL_USER_CREATION_FORM = 'users.forms.CustomUserCreationForm'
Allows the default `UserCreationForm` class to be overridden with a custom form when a custom user model is being used and extra fields are required in the user creation form.
For further information See {doc}`/advanced_topics/customisation/custom_user_models`.
```{versionchanged} 6.2
This setting has been deprecated in favor of customizing the form classes via `UserViewSet.get_form_class()` and will be removed in a future release. For further information, see [](custom_userviewset).
```
### `WAGTAIL_USER_CUSTOM_FIELDS`
@ -532,9 +536,11 @@ For further information See {doc}`/advanced_topics/customisation/custom_user_mod
WAGTAIL_USER_CUSTOM_FIELDS = ['country']
```
A list of the extra custom fields to be appended to the default list.
A list of the extra custom fields to be appended to the default list. The resulting list is passed to {class}`~django.forms.ModelForm`'s `Meta.fields` to generate the form fields.
For further information See {doc}`/advanced_topics/customisation/custom_user_models`.
```{versionchanged} 6.2
This setting has been deprecated in favor of customizing the form classes via `UserViewSet.get_form_class()` and will be removed in a future release. For further information, see [](custom_userviewset).
```
### `WAGTAILADMIN_USER_LOGIN_FORM`

Wyświetl plik

@ -149,6 +149,109 @@ class FooViewSet(SnippetViewSet):
return Permission.objects.filter(content_type=content_type)
```
### Deprecation of `WAGTAIL_USER_EDIT_FORM`, `WAGTAIL_USER_CREATION_FORM`, and `WAGTAIL_USER_CUSTOM_FIELDS` settings
This release introduces a customizable `UserViewSet` class, which can be used to customize various aspects of Wagtail's admin views for managing users, including the form classes for creating and editing users. As a result, the [`WAGTAIL_USER_EDIT_FORM`, `WAGTAIL_USER_CREATION_FORM`, and `WAGTAIL_USER_CUSTOM_FIELDS` settings](user_form_settings) have been deprecated in favor of customizing the form classes via `UserViewSet.get_form_class()`.
If you use the aforementioned settings, you can migrate your code by making the following changes.
#### Before
Given the following custom user model:
```py
class User(AbstractUser):
country = models.CharField(verbose_name='country', max_length=255)
status = models.ForeignKey(MembershipStatus, on_delete=models.SET_NULL, null=True, default=1)
```
The following custom forms:
```py
class CustomUserEditForm(UserEditForm):
status = forms.ModelChoiceField(queryset=MembershipStatus.objects, required=True, label=_("Status"))
class CustomUserCreationForm(UserCreationForm):
status = forms.ModelChoiceField(queryset=MembershipStatus.objects, required=True, label=_("Status"))
```
And the following settings:
```py
WAGTAIL_USER_EDIT_FORM = "myapp.forms.CustomUserEditForm"
WAGTAIL_USER_CREATION_FORM = "myapp.forms.CustomUserCreationForm"
WAGTAIL_USER_CUSTOM_FIELDS = ["country"]
```
#### After
Change the custom forms to the following:
```py
class CustomUserEditForm(UserEditForm):
status = forms.ModelChoiceField(queryset=MembershipStatus.objects, required=True, label=_("Status"))
# Use ModelForm's automatic form fields generation for the model's `country` field.
# Alternatively, you can also define a `country` form field directly on
# `CustomUserEditForm` along with any desired options for the field, and skip
# the following custom Meta subclass.
class Meta(UserEditForm.Meta):
fields = UserEditForm.Meta.fields | {"country"}
class CustomUserCreationForm(UserCreationForm):
status = forms.ModelChoiceField(queryset=MembershipStatus.objects, required=True, label=_("Status"))
# Use ModelForm's automatic form fields generation for the model's `country` field.
# Alternatively, you can also define a `country` form field directly on
# `CustomUserCreationForm` along with any desired options for the field, and skip
# the following custom Meta subclass.
class Meta(UserCreationForm.Meta):
fields = UserEditForm.Meta.fields | {"country"}
```
Create a custom `UserViewSet` subclass in e.g. `myapp/viewsets.py`:
```py
# myapp/viewsets.py
from wagtail.users.views.users import UserViewSet as WagtailUserViewSet
from .forms import CustomUserCreationForm, CustomUserEditForm
class UserViewSet(WagtailUserViewSet):
def get_form_class(self, for_update=False):
if for_update:
return CustomUserEditForm
return CustomUserCreationForm
```
Create a custom `WagtailUsersAppConfig` subclass in e.g. `myapp/apps.py` (or reuse the same class if you have a custom `GroupViewSet` as described in [](customizing_group_views)). Then, set a `user_viewset` attribute pointing to the custom `UserViewSet` subclass:
```py
# myapp/apps.py
from wagtail.users.apps import WagtailUsersAppConfig
class CustomUsersAppConfig(WagtailUsersAppConfig):
user_viewset = "myapp.viewsets.UserViewSet"
# If you have customized the GroupViewSet before
group_viewset = "myapp.viewsets.GroupViewSet"
```
Replace `wagtail.users` in `settings.INSTALLED_APPS` with the path to `CustomUsersAppConfig`:
```python
INSTALLED_APPS = [
...,
"myapp.apps.CustomUsersAppConfig",
# "wagtail.users",
...,
]
```
For more details, see [](custom_userviewset).
## Upgrade considerations - deprecation of old functionality
## Upgrade considerations - changes affecting Wagtail customisations

Wyświetl plik

@ -1,4 +1,5 @@
from itertools import groupby
from warnings import warn
from django import forms
from django.conf import settings
@ -21,6 +22,7 @@ from wagtail.models import (
GroupPagePermission,
Page,
)
from wagtail.utils.deprecation import RemovedInWagtail70Warning
User = get_user_model()
@ -29,6 +31,11 @@ standard_fields = {"email", "first_name", "last_name", "is_superuser", "groups"}
# Custom fields
if hasattr(settings, "WAGTAIL_USER_CUSTOM_FIELDS"):
custom_fields = set(settings.WAGTAIL_USER_CUSTOM_FIELDS)
warn(
"The `WAGTAIL_USER_CUSTOM_FIELDS` setting is deprecated. Use a custom "
"`UserViewSet` subclass and override `get_form_class()` instead.",
RemovedInWagtail70Warning,
)
else:
custom_fields = set()

Wyświetl plik

@ -33,7 +33,7 @@ from wagtail.models import (
)
from wagtail.test.utils import WagtailTestUtils
from wagtail.test.utils.template_tests import AdminTemplateTestUtils
from wagtail.users.forms import UserCreationForm, UserEditForm
from wagtail.users.forms import GroupForm, UserCreationForm, UserEditForm
from wagtail.users.models import UserProfile
from wagtail.users.permission_order import register as register_permission_order
from wagtail.users.views.groups import GroupViewSet
@ -57,6 +57,10 @@ def test_avatar_provider(user, default, size=50):
return "/nonexistent/path/to/avatar.png"
class CustomGroupForm(GroupForm):
pass
class CustomUserCreationForm(UserCreationForm):
country = forms.CharField(required=True, label="Country")
attachment = forms.FileField(required=True, label="Attachment")
@ -70,10 +74,18 @@ class CustomUserEditForm(UserEditForm):
class CustomGroupViewSet(GroupViewSet):
icon = "custom-icon"
def get_form_class(self, for_update=False):
return CustomGroupForm
class CustomUserViewSet(UserViewSet):
icon = "custom-icon"
def get_form_class(self, for_update=False):
if for_update:
return CustomUserEditForm
return CustomUserCreationForm
class TestUserFormHelpers(TestCase):
def test_get_user_edit_form_with_default_form(self):
@ -88,25 +100,45 @@ class TestUserFormHelpers(TestCase):
WAGTAIL_USER_CREATION_FORM="wagtail.users.tests.CustomUserCreationForm"
)
def test_get_user_creation_form_with_custom_form(self):
user_form = get_user_creation_form()
with self.assertWarnsMessage(
RemovedInWagtail70Warning,
"The `WAGTAIL_USER_CREATION_FORM` setting is deprecated. Use a custom "
"`UserViewSet` subclass and override `get_form_class()` instead.",
):
user_form = get_user_creation_form()
self.assertIs(user_form, CustomUserCreationForm)
@override_settings(WAGTAIL_USER_EDIT_FORM="wagtail.users.tests.CustomUserEditForm")
def test_get_user_edit_form_with_custom_form(self):
user_form = get_user_edit_form()
with self.assertWarnsMessage(
RemovedInWagtail70Warning,
"The `WAGTAIL_USER_EDIT_FORM` setting is deprecated. Use a custom "
"`UserViewSet` subclass and override `get_form_class()` instead.",
):
user_form = get_user_edit_form()
self.assertIs(user_form, CustomUserEditForm)
@override_settings(
WAGTAIL_USER_CREATION_FORM="wagtail.users.tests.CustomUserCreationFormDoesNotExist"
)
def test_get_user_creation_form_with_invalid_form(self):
self.assertRaises(ImproperlyConfigured, get_user_creation_form)
with self.assertWarnsMessage(
RemovedInWagtail70Warning,
"The `WAGTAIL_USER_CREATION_FORM` setting is deprecated. Use a custom "
"`UserViewSet` subclass and override `get_form_class()` instead.",
):
self.assertRaises(ImproperlyConfigured, get_user_creation_form)
@override_settings(
WAGTAIL_USER_EDIT_FORM="wagtail.users.tests.CustomUserEditFormDoesNotExist"
)
def test_get_user_edit_form_with_invalid_form(self):
self.assertRaises(ImproperlyConfigured, get_user_edit_form)
with self.assertWarnsMessage(
RemovedInWagtail70Warning,
"The `WAGTAIL_USER_EDIT_FORM` setting is deprecated. Use a custom "
"`UserViewSet` subclass and override `get_form_class()` instead.",
):
self.assertRaises(ImproperlyConfigured, get_user_edit_form)
class TestGroupUsersView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
@ -474,7 +506,6 @@ class TestUserCreateView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
)
@override_settings(
WAGTAIL_USER_CREATION_FORM="wagtail.users.tests.CustomUserCreationForm",
WAGTAIL_USER_CUSTOM_FIELDS=["country", "document"],
)
def test_create_with_custom_form(self):
response = self.post(
@ -2577,6 +2608,8 @@ class TestGroupViewSet(TestCase):
app_config_attr = "group_viewset"
default_viewset_cls = GroupViewSet
custom_viewset_cls = CustomGroupViewSet
create_form_cls = CustomGroupForm
edit_form_cls = CustomGroupForm
def setUp(self):
self.app_config = apps.get_app_config("wagtailusers")
@ -2596,6 +2629,9 @@ class TestGroupViewSet(TestCase):
group_viewset = get_viewset_cls(self.app_config, self.app_config_attr)
self.assertIs(group_viewset, self.custom_viewset_cls)
self.assertEqual(group_viewset.icon, "custom-icon")
viewset = group_viewset()
self.assertIs(viewset.get_form_class(for_update=False), self.create_form_cls)
self.assertIs(viewset.get_form_class(for_update=True), self.edit_form_cls)
def test_get_viewset_cls_custom_form_invalid_value(self):
with unittest.mock.patch.object(
@ -2626,6 +2662,8 @@ class TestUserViewSet(TestGroupViewSet):
app_config_attr = "user_viewset"
default_viewset_cls = UserViewSet
custom_viewset_cls = CustomUserViewSet
create_form_cls = CustomUserCreationForm
edit_form_cls = CustomUserEditForm
def test_registered_permissions(self):
group_ct = ContentType.objects.get_for_model(Group)

Wyświetl plik

@ -58,6 +58,11 @@ delete_user_perm = "{}.delete_{}".format(
def get_user_creation_form():
form_setting = "WAGTAIL_USER_CREATION_FORM"
if hasattr(settings, form_setting):
warn(
"The `WAGTAIL_USER_CREATION_FORM` setting is deprecated. Use a custom "
"`UserViewSet` subclass and override `get_form_class()` instead.",
RemovedInWagtail70Warning,
)
return get_custom_form(form_setting)
else:
return UserCreationForm
@ -66,6 +71,11 @@ def get_user_creation_form():
def get_user_edit_form():
form_setting = "WAGTAIL_USER_EDIT_FORM"
if hasattr(settings, form_setting):
warn(
"The `WAGTAIL_USER_EDIT_FORM` setting is deprecated. Use a custom "
"`UserViewSet` subclass and override `get_form_class()` instead.",
RemovedInWagtail70Warning,
)
return get_custom_form(form_setting)
else:
return UserEditForm