Migrate from auth.Group to a custom group model

This commit is contained in:
Jeremy Stretch 2024-02-28 15:09:17 -05:00
parent bc2b1e0709
commit 9f64e7d88f
25 changed files with 162 additions and 88 deletions

View File

@ -4,13 +4,13 @@ from collections import defaultdict
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.contrib.auth.backends import ModelBackend, RemoteUserBackend as _RemoteUserBackend from django.contrib.auth.backends import ModelBackend, RemoteUserBackend as _RemoteUserBackend
from django.contrib.auth.models import Group, AnonymousUser from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.db.models import Q from django.db.models import Q
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from users.constants import CONSTRAINT_TOKEN_USER from users.constants import CONSTRAINT_TOKEN_USER
from users.models import ObjectPermission from users.models import Group, ObjectPermission
from utilities.permissions import ( from utilities.permissions import (
permission_is_exempt, qs_filter_from_constraints, resolve_permission, resolve_permission_ct, permission_is_exempt, qs_filter_from_constraints, resolve_permission, resolve_permission_ct,
) )

View File

@ -392,19 +392,19 @@ ADMIN_MENU = Menu(
), ),
# Proxy model for auth.Group # Proxy model for auth.Group
MenuItem( MenuItem(
link=f'users:netboxgroup_list', link=f'users:group_list',
link_text=_('Groups'), link_text=_('Groups'),
permissions=[f'auth.view_group'], permissions=[f'auth.view_group'],
staff_only=True, staff_only=True,
buttons=( buttons=(
MenuItemButton( MenuItemButton(
link=f'users:netboxgroup_add', link=f'users:group_add',
title='Add', title='Add',
icon_class='mdi mdi-plus-thick', icon_class='mdi mdi-plus-thick',
permissions=[f'auth.add_group'] permissions=[f'auth.add_group']
), ),
MenuItemButton( MenuItemButton(
link=f'users:netboxgroup_import', link=f'users:group_import',
title='Import', title='Import',
icon_class='mdi mdi-upload', icon_class='mdi mdi-upload',
permissions=[f'auth.add_group'] permissions=[f'auth.add_group']

View File

@ -2,7 +2,6 @@ import datetime
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.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.test import Client from django.test import Client
from django.test.utils import override_settings from django.test.utils import override_settings
@ -12,7 +11,7 @@ from rest_framework.test import APIClient
from dcim.models import Site from dcim.models import Site
from ipam.models import Prefix from ipam.models import Prefix
from users.models import ObjectPermission, Token from users.models import Group, ObjectPermission, Token
from utilities.testing import TestCase from utilities.testing import TestCase
from utilities.testing.api import APITestCase from utilities.testing.api import APITestCase

View File

@ -24,7 +24,7 @@
<div class="card"> <div class="card">
<h5 class="card-header">{% trans "Users" %}</h5> <h5 class="card-header">{% trans "Users" %}</h5>
<div class="list-group list-group-flush"> <div class="list-group list-group-flush">
{% for user in object.user_set.all %} {% for user in object.users.all %}
<a href="{% url 'users:user' pk=user.pk %}" class="list-group-item list-group-item-action">{{ user }}</a> <a href="{% url 'users:user' pk=user.pk %}" class="list-group-item list-group-item-action">{{ user }}</a>
{% empty %} {% empty %}
<div class="list-group-item text-muted">{% trans "None" %}</div> <div class="list-group-item text-muted">{% trans "None" %}</div>

View File

@ -82,7 +82,7 @@
<h5 class="card-header">{% trans "Assigned Groups" %}</h5> <h5 class="card-header">{% trans "Assigned Groups" %}</h5>
<div class="list-group list-group-flush"> <div class="list-group list-group-flush">
{% for group in object.groups.all %} {% for group in object.groups.all %}
<a href="{% url 'users:netboxgroup' pk=group.pk %}" class="list-group-item list-group-item-action">{{ group }}</a> <a href="{% url 'users:group' pk=group.pk %}" class="list-group-item list-group-item-action">{{ group }}</a>
{% empty %} {% empty %}
<div class="list-group-item text-muted">{% trans "None" %}</div> <div class="list-group-item text-muted">{% trans "None" %}</div>
{% endfor %} {% endfor %}

View File

@ -53,7 +53,7 @@
<h5 class="card-header">{% trans "Assigned Groups" %}</h5> <h5 class="card-header">{% trans "Assigned Groups" %}</h5>
<div class="list-group list-group-flush"> <div class="list-group list-group-flush">
{% for group in object.groups.all %} {% for group in object.groups.all %}
<a href="{% url 'users:netboxgroup' pk=group.pk %}" class="list-group-item list-group-item-action">{{ group }}</a> <a href="{% url 'users:group' pk=group.pk %}" class="list-group-item list-group-item-action">{{ group }}</a>
{% empty %} {% empty %}
<div class="list-group-item text-muted">{% trans "None" %}</div> <div class="list-group-item text-muted">{% trans "None" %}</div>
{% endfor %} {% endfor %}

View File

@ -1,5 +1,4 @@
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from drf_spectacular.utils import extend_schema_field from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
@ -7,7 +6,7 @@ from rest_framework import serializers
from netbox.api.fields import ContentTypeField from netbox.api.fields import ContentTypeField
from netbox.api.serializers import WritableNestedSerializer from netbox.api.serializers import WritableNestedSerializer
from users.models import ObjectPermission, Token from users.models import Group, ObjectPermission, Token
__all__ = [ __all__ = [
'NestedGroupSerializer', 'NestedGroupSerializer',

View File

@ -1,7 +1,6 @@
from django.conf import settings from django.conf import settings
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from drf_spectacular.utils import extend_schema_field from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
@ -10,7 +9,7 @@ from rest_framework.exceptions import AuthenticationFailed, PermissionDenied
from netbox.api.fields import ContentTypeField, IPNetworkSerializer, SerializedPKRelatedField from netbox.api.fields import ContentTypeField, IPNetworkSerializer, SerializedPKRelatedField
from netbox.api.serializers import ValidatedModelSerializer from netbox.api.serializers import ValidatedModelSerializer
from users.models import ObjectPermission, Token from users.models import Group, ObjectPermission, Token
from .nested_serializers import * from .nested_serializers import *

View File

@ -1,11 +1,9 @@
import logging import logging
from django.contrib.auth import authenticate
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.db.models import Count from django.db.models import Count
from drf_spectacular.utils import extend_schema
from drf_spectacular.types import OpenApiTypes from drf_spectacular.types import OpenApiTypes
from rest_framework.exceptions import AuthenticationFailed from drf_spectacular.utils import extend_schema
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.routers import APIRootView from rest_framework.routers import APIRootView
@ -15,7 +13,7 @@ from rest_framework.viewsets import ViewSet
from netbox.api.viewsets import NetBoxModelViewSet from netbox.api.viewsets import NetBoxModelViewSet
from users import filtersets from users import filtersets
from users.models import ObjectPermission, Token, UserConfig from users.models import Group, ObjectPermission, Token, UserConfig
from utilities.querysets import RestrictedQuerySet from utilities.querysets import RestrictedQuerySet
from utilities.utils import deepmerge from utilities.utils import deepmerge
from . import serializers from . import serializers
@ -40,7 +38,7 @@ class UserViewSet(NetBoxModelViewSet):
class GroupViewSet(NetBoxModelViewSet): class GroupViewSet(NetBoxModelViewSet):
queryset = RestrictedQuerySet(model=Group).annotate(user_count=Count('user')).order_by('name') queryset = Group.objects.annotate(user_count=Count('user'))
serializer_class = serializers.GroupSerializer serializer_class = serializers.GroupSerializer
filterset_class = filtersets.GroupFilterSet filterset_class = filtersets.GroupFilterSet

View File

@ -1,11 +1,10 @@
import django_filters import django_filters
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.db.models import Q from django.db.models import Q
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from netbox.filtersets import BaseFilterSet from netbox.filtersets import BaseFilterSet
from users.models import ObjectPermission, Token from users.models import Group, ObjectPermission, Token
__all__ = ( __all__ = (
'GroupFilterSet', 'GroupFilterSet',

View File

@ -14,7 +14,7 @@ __all__ = (
class GroupImportForm(CSVModelForm): class GroupImportForm(CSVModelForm):
class Meta: class Meta:
model = NetBoxGroup model = Group
fields = ( fields = (
'name', 'name',
) )

View File

@ -1,11 +1,10 @@
from django import forms from django import forms
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from netbox.forms import NetBoxModelFilterSetForm from netbox.forms import NetBoxModelFilterSetForm
from netbox.forms.mixins import SavedFiltersMixin from netbox.forms.mixins import SavedFiltersMixin
from users.models import NetBoxGroup, User, ObjectPermission, Token from users.models import Group, ObjectPermission, Token, User
from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, FilterForm from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, FilterForm
from utilities.forms.fields import DynamicModelMultipleChoiceField from utilities.forms.fields import DynamicModelMultipleChoiceField
from utilities.forms.widgets import DateTimePicker from utilities.forms.widgets import DateTimePicker
@ -19,7 +18,7 @@ __all__ = (
class GroupFilterForm(NetBoxModelFilterSetForm): class GroupFilterForm(NetBoxModelFilterSetForm):
model = NetBoxGroup model = Group
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id',)), (None, ('q', 'filter_id',)),
) )

View File

@ -1,7 +1,6 @@
from django import forms from django import forms
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.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.forms import SimpleArrayField from django.contrib.postgres.forms import SimpleArrayField
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
@ -253,7 +252,7 @@ class GroupForm(forms.ModelForm):
) )
class Meta: class Meta:
model = NetBoxGroup model = Group
fields = [ fields = [
'name', 'users', 'object_permissions', 'name', 'users', 'object_permissions',
] ]
@ -263,14 +262,14 @@ class GroupForm(forms.ModelForm):
# Populate assigned users and permissions # Populate assigned users and permissions
if self.instance.pk: if self.instance.pk:
self.fields['users'].initial = self.instance.user_set.values_list('id', flat=True) self.fields['users'].initial = self.instance.users.values_list('id', flat=True)
self.fields['object_permissions'].initial = self.instance.object_permissions.values_list('id', flat=True) self.fields['object_permissions'].initial = self.instance.object_permissions.values_list('id', flat=True)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
instance = super().save(*args, **kwargs) instance = super().save(*args, **kwargs)
# Update assigned users and permissions # Update assigned users and permissions
instance.user_set.set(self.cleaned_data['users']) instance.users.set(self.cleaned_data['users'])
instance.object_permissions.set(self.cleaned_data['object_permissions']) instance.object_permissions.set(self.cleaned_data['object_permissions'])
return instance return instance

View File

@ -1,10 +1,10 @@
import graphene import graphene
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from netbox.graphql.fields import ObjectField, ObjectListField from netbox.graphql.fields import ObjectField, ObjectListField
from .types import * from users.models import Group
from utilities.graphql_optimizer import gql_query_optimizer from utilities.graphql_optimizer import gql_query_optimizer
from .types import *
class UsersQuery(graphene.ObjectType): class UsersQuery(graphene.ObjectType):

View File

@ -1,8 +1,8 @@
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from graphene_django import DjangoObjectType from graphene_django import DjangoObjectType
from users import filtersets from users import filtersets
from users.models import Group
from utilities.querysets import RestrictedQuerySet from utilities.querysets import RestrictedQuerySet
__all__ = ( __all__ = (

View File

@ -0,0 +1,55 @@
import users.models
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0005_alter_user_table'),
]
operations = [
# Create the new Group model & table
migrations.CreateModel(
name='Group',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
('name', models.CharField(max_length=150, unique=True)),
('description', models.CharField(blank=True, max_length=200)),
('permissions', models.ManyToManyField(blank=True, related_name='groups', related_query_name='group', to='auth.permission')),
],
options={
'verbose_name': 'group',
'verbose_name_plural': 'groups',
},
managers=[
('objects', users.models.NetBoxGroupManager()),
],
),
# Copy existing groups from the old table into the new one
migrations.RunSQL(
"INSERT INTO users_group (SELECT id, name, '' AS description FROM auth_group)"
),
# Update the sequence for group ID values
migrations.RunSQL(
"SELECT setval('users_group_id_seq', (SELECT MAX(id) FROM users_group))"
),
# Update the "groups" M2M fields on User & ObjectPermission
migrations.AlterField(
model_name='user',
name='groups',
field=models.ManyToManyField(blank=True, related_name='users', related_query_name='user', to='users.group'),
),
migrations.AlterField(
model_name='objectpermission',
name='groups',
field=models.ManyToManyField(blank=True, related_name='object_permissions', to='users.group'),
),
migrations.DeleteModel(
name='NetBoxGroup',
),
]

View File

@ -4,7 +4,12 @@ import os
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.contrib.auth.models import ( from django.contrib.auth.models import (
AbstractUser, Group, GroupManager, User as DjangoUser, UserManager as DjangoUserManager AbstractUser,
Group as DjangoGroup,
GroupManager,
Permission,
User as DjangoUser,
UserManager as DjangoUserManager
) )
from django.contrib.postgres.fields import ArrayField from django.contrib.postgres.fields import ArrayField
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
@ -25,7 +30,7 @@ from utilities.utils import flatten_dict
from .constants import * from .constants import *
__all__ = ( __all__ = (
'NetBoxGroup', 'Group',
'ObjectPermission', 'ObjectPermission',
'Token', 'Token',
'User', 'User',
@ -33,22 +38,61 @@ __all__ = (
) )
# class NetBoxGroupManager(GroupManager.from_queryset(RestrictedQuerySet)):
# Proxies for Django's User and Group models pass
#
class Group(models.Model):
name = models.CharField(
verbose_name=_('name'),
max_length=150,
unique=True
)
description = models.CharField(
verbose_name=_('description'),
max_length=200,
blank=True
)
# Replicate legacy Django permissions support from stock Group model
# to ensure authentication backend compatibility
permissions = models.ManyToManyField(
Permission,
verbose_name=_("permissions"),
blank=True,
related_name='groups',
related_query_name='group'
)
objects = NetBoxGroupManager()
class Meta:
verbose_name = _('group')
verbose_name_plural = _('groups')
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('users:group', args=[self.pk])
def natural_key(self):
return (self.name,)
class UserManager(DjangoUserManager.from_queryset(RestrictedQuerySet)): class UserManager(DjangoUserManager.from_queryset(RestrictedQuerySet)):
pass pass
class NetBoxGroupManager(GroupManager.from_queryset(RestrictedQuerySet)):
pass
class User(AbstractUser): class User(AbstractUser):
""" groups = models.ManyToManyField(
Proxy contrib.auth.models.User for the UI to='users.Group',
""" verbose_name=_('groups'),
blank=True,
related_name='users',
related_query_name='user'
)
objects = UserManager() objects = UserManager()
class Meta: class Meta:
@ -68,22 +112,6 @@ class User(AbstractUser):
raise ValidationError(_("A user with this username already exists.")) raise ValidationError(_("A user with this username already exists."))
class NetBoxGroup(Group):
"""
Proxy contrib.auth.models.User for the UI
"""
objects = NetBoxGroupManager()
class Meta:
proxy = True
ordering = ('name',)
verbose_name = _('group')
verbose_name_plural = _('groups')
def get_absolute_url(self):
return reverse('users:netboxgroup', args=[self.pk])
# #
# User preferences # User preferences
# #
@ -360,7 +388,7 @@ class ObjectPermission(models.Model):
related_name='object_permissions' related_name='object_permissions'
) )
groups = models.ManyToManyField( groups = models.ManyToManyField(
to=Group, to='users.Group',
blank=True, blank=True,
related_name='object_permissions' related_name='object_permissions'
) )

View File

@ -3,7 +3,7 @@ from django.utils.translation import gettext as _
from account.tables import UserTokenTable from account.tables import UserTokenTable
from netbox.tables import NetBoxTable, columns from netbox.tables import NetBoxTable, columns
from users.models import NetBoxGroup, User, ObjectPermission, Token from users.models import Group, ObjectPermission, Token, User
__all__ = ( __all__ = (
'GroupTable', 'GroupTable',
@ -33,7 +33,7 @@ class UserTable(NetBoxTable):
) )
groups = columns.ManyToManyColumn( groups = columns.ManyToManyColumn(
verbose_name=_('Groups'), verbose_name=_('Groups'),
linkify_item=('users:netboxgroup', {'pk': tables.A('pk')}) linkify_item=('users:group', {'pk': tables.A('pk')})
) )
is_active = columns.BooleanColumn( is_active = columns.BooleanColumn(
verbose_name=_('Is Active'), verbose_name=_('Is Active'),
@ -67,7 +67,7 @@ class GroupTable(NetBoxTable):
) )
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = NetBoxGroup model = Group
fields = ( fields = (
'pk', 'id', 'name', 'users_count', 'pk', 'id', 'name', 'users_count',
) )
@ -107,7 +107,7 @@ class ObjectPermissionTable(NetBoxTable):
) )
groups = columns.ManyToManyColumn( groups = columns.ManyToManyColumn(
verbose_name=_('Groups'), verbose_name=_('Groups'),
linkify_item=('users:netboxgroup', {'pk': tables.A('pk')}) linkify_item=('users:group', {'pk': tables.A('pk')})
) )
actions = columns.ActionsColumn( actions = columns.ActionsColumn(
actions=('edit', 'delete'), actions=('edit', 'delete'),

View File

@ -1,9 +1,8 @@
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.urls import reverse from django.urls import reverse
from users.models import ObjectPermission, Token from users.models import Group, ObjectPermission, Token
from utilities.testing import APIViewTestCases, APITestCase, create_test_user from utilities.testing import APIViewTestCases, APITestCase, create_test_user
from utilities.utils import deepmerge from utilities.utils import deepmerge

View File

@ -1,13 +1,12 @@
import datetime import datetime
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.test import TestCase from django.test import TestCase
from django.utils.timezone import make_aware from django.utils.timezone import make_aware
from users import filtersets from users import filtersets
from users.models import ObjectPermission, Token from users.models import Group, ObjectPermission, Token
from utilities.testing import BaseFilterSetTests from utilities.testing import BaseFilterSetTests
User = get_user_model() User = get_user_model()

View File

@ -1,4 +1,3 @@
from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from users.models import * from users.models import *
@ -70,7 +69,7 @@ class GroupTestCase(
ViewTestCases.BulkImportObjectsViewTestCase, ViewTestCases.BulkImportObjectsViewTestCase,
ViewTestCases.BulkDeleteObjectsViewTestCase, ViewTestCases.BulkDeleteObjectsViewTestCase,
): ):
model = NetBoxGroup model = Group
maxDiff = None maxDiff = None
@classmethod @classmethod

View File

@ -23,11 +23,11 @@ urlpatterns = [
path('users/<int:pk>/', include(get_model_urls('users', 'user'))), path('users/<int:pk>/', include(get_model_urls('users', 'user'))),
# Groups # Groups
path('groups/', views.GroupListView.as_view(), name='netboxgroup_list'), path('groups/', views.GroupListView.as_view(), name='group_list'),
path('groups/add/', views.GroupEditView.as_view(), name='netboxgroup_add'), path('groups/add/', views.GroupEditView.as_view(), name='group_add'),
path('groups/import/', views.GroupBulkImportView.as_view(), name='netboxgroup_import'), path('groups/import/', views.GroupBulkImportView.as_view(), name='group_import'),
path('groups/delete/', views.GroupBulkDeleteView.as_view(), name='netboxgroup_bulk_delete'), path('groups/delete/', views.GroupBulkDeleteView.as_view(), name='group_bulk_delete'),
path('groups/<int:pk>/', include(get_model_urls('users', 'netboxgroup'))), path('groups/<int:pk>/', include(get_model_urls('users', 'group'))),
# Permissions # Permissions
path('permissions/', views.ObjectPermissionListView.as_view(), name='objectpermission_list'), path('permissions/', views.ObjectPermissionListView.as_view(), name='objectpermission_list'),

View File

@ -5,7 +5,7 @@ from extras.tables import ObjectChangeTable
from netbox.views import generic from netbox.views import generic
from utilities.views import register_model_view from utilities.views import register_model_view
from . import filtersets, forms, tables from . import filtersets, forms, tables
from .models import NetBoxGroup, User, ObjectPermission, Token from .models import Group, User, ObjectPermission, Token
# #
@ -110,36 +110,36 @@ class UserBulkDeleteView(generic.BulkDeleteView):
# #
class GroupListView(generic.ObjectListView): class GroupListView(generic.ObjectListView):
queryset = NetBoxGroup.objects.annotate(users_count=Count('user')) queryset = Group.objects.annotate(users_count=Count('user'))
filterset = filtersets.GroupFilterSet filterset = filtersets.GroupFilterSet
filterset_form = forms.GroupFilterForm filterset_form = forms.GroupFilterForm
table = tables.GroupTable table = tables.GroupTable
@register_model_view(NetBoxGroup) @register_model_view(Group)
class GroupView(generic.ObjectView): class GroupView(generic.ObjectView):
queryset = NetBoxGroup.objects.all() queryset = Group.objects.all()
template_name = 'users/group.html' template_name = 'users/group.html'
@register_model_view(NetBoxGroup, 'edit') @register_model_view(Group, 'edit')
class GroupEditView(generic.ObjectEditView): class GroupEditView(generic.ObjectEditView):
queryset = NetBoxGroup.objects.all() queryset = Group.objects.all()
form = forms.GroupForm form = forms.GroupForm
@register_model_view(NetBoxGroup, 'delete') @register_model_view(Group, 'delete')
class GroupDeleteView(generic.ObjectDeleteView): class GroupDeleteView(generic.ObjectDeleteView):
queryset = NetBoxGroup.objects.all() queryset = Group.objects.all()
class GroupBulkImportView(generic.BulkImportView): class GroupBulkImportView(generic.BulkImportView):
queryset = NetBoxGroup.objects.all() queryset = Group.objects.all()
model_form = forms.GroupImportForm model_form = forms.GroupImportForm
class GroupBulkDeleteView(generic.BulkDeleteView): class GroupBulkDeleteView(generic.BulkDeleteView):
queryset = NetBoxGroup.objects.annotate(users_count=Count('user')) queryset = Group.objects.annotate(users_count=Count('user'))
filterset = filtersets.GroupFilterSet filterset = filtersets.GroupFilterSet
table = tables.GroupTable table = tables.GroupTable

View File

@ -32,6 +32,7 @@ def get_serializer_for_model(model, prefix=''):
Dynamically resolve and return the appropriate serializer for a model. Dynamically resolve and return the appropriate serializer for a model.
""" """
app_name, model_name = model._meta.label.split('.') app_name, model_name = model._meta.label.split('.')
# TODO: Remove this logic
# Serializers for Django's auth models are in the users app # Serializers for Django's auth models are in the users app
if app_name == 'auth': if app_name == 'auth':
app_name = 'users' app_name = 'users'

View File

@ -51,6 +51,7 @@ def get_viewname(model, action=None, rest_api=False):
if is_plugin: if is_plugin:
viewname = f'plugins-api:{app_label}-api:{model_name}' viewname = f'plugins-api:{app_label}-api:{model_name}'
else: else:
# TODO: Remove this logic
# Alter the app_label for group and user model_name to point to users app # Alter the app_label for group and user model_name to point to users app
if app_label == 'auth' and model_name in ['group', 'user']: if app_label == 'auth' and model_name in ['group', 'user']:
app_label = 'users' app_label = 'users'