Kaynağa Gözat

Introduce API endpoints for Users and Groups

Jeremy Stretch 5 yıl önce
ebeveyn
işleme
1ac215bf87

+ 6 - 3
netbox/users/api/nested_serializers.py

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

+ 26 - 0
netbox/users/api/serializers.py

@@ -7,6 +7,32 @@ from utilities.api import ContentTypeField, SerializedPKRelatedField, ValidatedM
 from .nested_serializers import *
 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):
 class ObjectPermissionSerializer(ValidatedModelSerializer):
     url = serializers.HyperlinkedIdentityField(view_name='users-api:objectpermission-detail')
     url = serializers.HyperlinkedIdentityField(view_name='users-api:objectpermission-detail')
     object_types = ContentTypeField(
     object_types = ContentTypeField(

+ 4 - 0
netbox/users/api/urls.py

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

+ 21 - 1
netbox/users/api/views.py

@@ -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.api import ModelViewSet
+from utilities.querysets import RestrictedQuerySet
 from . import serializers
 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 - 0
netbox/users/filters.py

@@ -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)
+        )