diff --git a/docs/configuration/dynamic-settings.md b/docs/configuration/dynamic-settings.md
index a222272c2..5649eb9be 100644
--- a/docs/configuration/dynamic-settings.md
+++ b/docs/configuration/dynamic-settings.md
@@ -66,6 +66,22 @@ CUSTOM_VALIDATORS = {
---
+## DEFAULT_USER_PREFERENCES
+
+This is a dictionary defining the default preferences to be set for newly-created user accounts. For example, to set the default page size for all users to 100, define the following:
+
+```python
+DEFAULT_USER_PREFERENCES = {
+ "pagination": {
+ "per_page": 100
+ }
+}
+```
+
+For a complete list of available preferences, log into NetBox and navigate to `/user/preferences/`. A period in a preference name indicates a level of nesting in the JSON data. The example above maps to `pagination.per_page`.
+
+---
+
## ENFORCE_GLOBAL_UNIQUE
Default: False
diff --git a/netbox/extras/admin.py b/netbox/extras/admin.py
index b6ee01db9..2c98d2a81 100644
--- a/netbox/extras/admin.py
+++ b/netbox/extras/admin.py
@@ -33,6 +33,9 @@ class ConfigRevisionAdmin(admin.ModelAdmin):
('NAPALM', {
'fields': ('NAPALM_USERNAME', 'NAPALM_PASSWORD', 'NAPALM_TIMEOUT', 'NAPALM_ARGS'),
}),
+ ('User Preferences', {
+ 'fields': ('DEFAULT_USER_PREFERENCES',),
+ }),
('Miscellaneous', {
'fields': ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'MAPS_URL'),
}),
diff --git a/netbox/netbox/config/parameters.py b/netbox/netbox/config/parameters.py
index b4f16bf28..d3ebc7bff 100644
--- a/netbox/netbox/config/parameters.py
+++ b/netbox/netbox/config/parameters.py
@@ -131,6 +131,15 @@ PARAMS = (
field=forms.JSONField
),
+ # User preferences
+ ConfigParam(
+ name='DEFAULT_USER_PREFERENCES',
+ label='Default preferences',
+ default={},
+ description="Default preferences for new users",
+ field=forms.JSONField
+ ),
+
# Miscellaneous
ConfigParam(
name='MAINTENANCE_MODE',
diff --git a/netbox/users/forms.py b/netbox/users/forms.py
index 5a4b1c2ff..721c68e43 100644
--- a/netbox/users/forms.py
+++ b/netbox/users/forms.py
@@ -1,5 +1,6 @@
from django import forms
from django.contrib.auth.forms import AuthenticationForm, PasswordChangeForm as DjangoPasswordChangeForm
+from django.utils.html import mark_safe
from utilities.forms import BootstrapMixin, DateTimePicker, StaticSelect
from utilities.utils import flatten_dict
@@ -22,10 +23,12 @@ class UserConfigFormMetaclass(forms.models.ModelFormMetaclass):
# Emulate a declared field for each supported user preference
preference_fields = {}
for field_name, preference in PREFERENCES.items():
+ description = f'{preference.description}
' if preference.description else ''
+ help_text = f'{description}{field_name}
'
field_kwargs = {
'label': preference.label,
'choices': preference.choices,
- 'help_text': preference.description,
+ 'help_text': mark_safe(help_text),
'coerce': preference.coerce,
'required': False,
'widget': StaticSelect,
diff --git a/netbox/users/models.py b/netbox/users/models.py
index 64b6432a7..7b768b57f 100644
--- a/netbox/users/models.py
+++ b/netbox/users/models.py
@@ -10,6 +10,7 @@ from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils import timezone
+from netbox.config import get_config
from netbox.models import BigIDModel
from utilities.querysets import RestrictedQuerySet
from utilities.utils import flatten_dict
@@ -166,7 +167,8 @@ def create_userconfig(instance, created, **kwargs):
Automatically create a new UserConfig when a new User is created.
"""
if created:
- UserConfig(user=instance).save()
+ config = get_config()
+ UserConfig(user=instance, data=config.DEFAULT_USER_PREFERENCES).save()
#
diff --git a/netbox/users/preferences.py b/netbox/users/preferences.py
index 18c3dbac0..635393913 100644
--- a/netbox/users/preferences.py
+++ b/netbox/users/preferences.py
@@ -31,6 +31,7 @@ PREFERENCES = {
'pagination.per_page': UserPreference(
label='Page length',
choices=get_page_lengths(),
+ description='The number of objects to display per page',
coerce=lambda x: int(x)
),