Introduce API endpoints for Users and Groups

This commit is contained in:
Jeremy Stretch 2020-07-22 11:21:51 -04:00
parent 3e6b257fa0
commit 1ac215bf87
5 changed files with 115 additions and 4 deletions

View File

@ -13,20 +13,23 @@ __all__ = [
class NestedGroupSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='users-api:group-detail')
class Meta:
model = Group
fields = ['id', 'name']
fields = ['id', 'url', 'name']
class NestedUserSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='users-api:user-detail')
class Meta:
model = User
fields = ['id', 'username']
fields = ['id', 'url', 'username']
class NestedObjectPermissionSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='users-api:objectpermission-detail')
object_types = ContentTypeField(
queryset=ContentType.objects.all(),
many=True
@ -36,7 +39,7 @@ class NestedObjectPermissionSerializer(WritableNestedSerializer):
class Meta:
model = ObjectPermission
fields = ['id', 'name', 'enabled', 'object_types', 'groups', 'users', 'actions']
fields = ['id', 'url', 'name', 'enabled', 'object_types', 'groups', 'users', 'actions']
def get_groups(self, obj):
return [g.name for g in obj.groups.all()]

View File

@ -7,6 +7,32 @@ from utilities.api import ContentTypeField, SerializedPKRelatedField, ValidatedM
from .nested_serializers import *
class UserSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='users-api:user-detail')
groups = SerializedPKRelatedField(
queryset=Group.objects.all(),
serializer=NestedGroupSerializer,
required=False,
many=True
)
class Meta:
model = User
fields = (
'id', 'url', 'username', 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'date_joined',
'groups',
)
class GroupSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='users-api:group-detail')
user_count = serializers.IntegerField(read_only=True)
class Meta:
model = Group
fields = ('id', 'url', 'name', 'user_count')
class ObjectPermissionSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='users-api:objectpermission-detail')
object_types = ContentTypeField(

View File

@ -14,6 +14,10 @@ class UsersRootView(routers.APIRootView):
router = routers.DefaultRouter()
router.APIRootView = UsersRootView
# Users and groups
router.register('users', views.UserViewSet)
router.register('groups', views.GroupViewSet)
# Permissions
router.register('permissions', views.ObjectPermissionViewSet)

View File

@ -1,7 +1,27 @@
from django.contrib.auth.models import Group, User
from django.db.models import Count
from users import filters
from users.models import ObjectPermission
from utilities.api import ModelViewSet
from utilities.querysets import RestrictedQuerySet
from . import serializers
from users.models import ObjectPermission
#
# Users and groups
#
class UserViewSet(ModelViewSet):
queryset = RestrictedQuerySet(model=User).prefetch_related('groups')
serializer_class = serializers.UserSerializer
filterset_class = filters.UserFitlerSet
class GroupViewSet(ModelViewSet):
queryset = RestrictedQuerySet(model=Group).annotate(user_count=Count('user'))
serializer_class = serializers.GroupSerializer
filterset_class = filters.GroupFitlerSet
#

58
netbox/users/filters.py Normal file
View File

@ -0,0 +1,58 @@
import django_filters
from django.contrib.auth.models import Group, User
from django.db.models import Q
from utilities.filters import BaseFilterSet
__all__ = (
'GroupFitlerSet',
'UserFitlerSet',
)
class GroupFitlerSet(BaseFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
class Meta:
model = Group
fields = ['id', 'name']
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(name__icontains=value)
class UserFitlerSet(BaseFilterSet):
q = django_filters.CharFilter(
method='search',
label='Search',
)
group_id = django_filters.ModelMultipleChoiceFilter(
field_name='groups',
queryset=Group.objects.all(),
label='Group',
)
group = django_filters.ModelMultipleChoiceFilter(
field_name='groups__name',
queryset=Group.objects.all(),
to_field_name='name',
label='Group (name)',
)
class Meta:
model = User
fields = ['id', 'username', 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'date_joined']
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(username__icontains=value) |
Q(first_name__icontains=value) |
Q(last_name__icontains=value) |
Q(email__icontains=value)
)