From d946c65dbeac2f0a5f88ad1c239aea9c13120956 Mon Sep 17 00:00:00 2001
From: Brandon Rodriguez <brodriguez8774@gmail.com>
Date: Fri, 1 Mar 2024 15:58:19 -0500
Subject: [PATCH] Create some basic Django REST testing view logic and setup

---
 django_rest/Pipfile                 |  6 ++++
 django_rest/settings/settings.py    | 16 ++++++++++
 django_rest/settings/urls.py        | 12 ++++++++
 django_rest/test_app/routes.py      | 21 +++++++++++++
 django_rest/test_app/serializers.py | 46 +++++++++++++++++++++++++++++
 django_rest/test_app/urls.py        |  2 +-
 django_rest/test_app/views.py       | 29 ++++++++++++++++++
 7 files changed, 131 insertions(+), 1 deletion(-)
 create mode 100644 django_rest/test_app/routes.py
 create mode 100644 django_rest/test_app/serializers.py

diff --git a/django_rest/Pipfile b/django_rest/Pipfile
index 36e8f3a..7cb12ea 100644
--- a/django_rest/Pipfile
+++ b/django_rest/Pipfile
@@ -25,6 +25,12 @@ django-adminlte2-pdq = "*"      # Adds framework for easily styling site like ad
 django-localflavor = "*"        # Easy implementation of localization info, such as addresses.
 requests = "*"                  # Simple HTTP library. Useful for things like initiating API requests.
 
+# Django REST dependencies.
+djangorestframework = "*"       # Core Django REST package.
+markdown = "*"                  # Markdown support for browsable API.
+django-filter = "*"             # API filtering support.
+
+
 ###
  # Development and testing packages, installed via `pipenv sync --dev`.
  ##
diff --git a/django_rest/settings/settings.py b/django_rest/settings/settings.py
index a243260..4bbc520 100644
--- a/django_rest/settings/settings.py
+++ b/django_rest/settings/settings.py
@@ -43,6 +43,9 @@ INSTALLED_APPS = [
     # DjangoETC Package.
     'django_expanded_test_cases',
 
+    # Django REST Package.
+    'rest_framework',
+
     # Built-in Django apps.
     'django.contrib.admin',
     'django.contrib.auth',
@@ -140,3 +143,16 @@ STATIC_URL = 'static/'
 # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
 
 DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+
+
+# Django REST settings.
+REST_FRAMEWORK = {
+    # Use Django's standard `django.contrib.auth` permissions, or allow read-only access for unauthenticated users.
+    'DEFAULT_PERMISSION_CLASSES': [
+        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
+    ],
+
+    # API pagination settings.
+    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
+    'PAGE_SIZE': 10,
+}
diff --git a/django_rest/settings/urls.py b/django_rest/settings/urls.py
index 3f9b160..dba9af2 100644
--- a/django_rest/settings/urls.py
+++ b/django_rest/settings/urls.py
@@ -13,9 +13,17 @@ Including another URLconf
     1. Import the include() function: from django.urls import include, path
     2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
 """
+
+# System Imports.
+
+# Third-Party Imports.
 from django.contrib import admin
 from django.urls import include, path
 
+# Internal Imports.
+from test_app.routes import router
+
+
 urlpatterns = [
     # Django Admin views.
     path('admin/', admin.site.urls),
@@ -26,6 +34,10 @@ urlpatterns = [
     # Basic/minimalistic Django application.
     path('test_app/', include('test_app.urls')),
 
+    # Django REST views.
+    path('rest/', include(router.urls)),
+    path('rest/api-auth/', include('rest_framework.urls')),
+
     # Package testing views.
 
     # AdminLTE2 routes for demo purposes.
diff --git a/django_rest/test_app/routes.py b/django_rest/test_app/routes.py
new file mode 100644
index 0000000..1684c39
--- /dev/null
+++ b/django_rest/test_app/routes.py
@@ -0,0 +1,21 @@
+"""
+Urls for Django REST test project app.
+"""
+
+
+# System Imports.
+
+# Third-Party Imports.
+from rest_framework import routers
+
+# Internal Imports.
+
+
+from test_app import views
+router = routers.DefaultRouter()
+
+# Hyperlink API Views.
+
+# Model API Views.
+router.register(r'users', views.UserModelViewSet)
+router.register(r'groups', views.GroupModelViewSet)
diff --git a/django_rest/test_app/serializers.py b/django_rest/test_app/serializers.py
new file mode 100644
index 0000000..7003371
--- /dev/null
+++ b/django_rest/test_app/serializers.py
@@ -0,0 +1,46 @@
+"""
+Views for Django REST test project serializers.
+"""
+
+# System Imports.
+
+# Third-Party Imports.
+from django.contrib.auth import get_user_model
+from django.contrib.auth.models import Group
+from rest_framework import serializers
+
+# Internal Imports.
+
+
+class UserSerializer(serializers.ModelSerializer):
+    """Serializer for User model."""
+
+    class Meta:
+        model = get_user_model()
+        fields = [
+            'username',
+            'email',
+            'first_name',
+            'last_name',
+            'password',
+            'is_active',
+            'is_superuser',
+            'is_staff',
+            'user_permissions',
+            'groups',
+            'last_login',
+            'date_joined',
+        ]
+
+
+class GroupSerializer(serializers.ModelSerializer):
+    """Serializer for Django PermissionGroup model."""
+
+    # Model Fields.
+    id = serializers.IntegerField(read_only=True)
+    name = serializers.CharField(max_length=255)
+
+    class Meta:
+        model = Group
+        fields = ['name', 'permissions']
+
diff --git a/django_rest/test_app/urls.py b/django_rest/test_app/urls.py
index e9245a2..4ac5e8f 100644
--- a/django_rest/test_app/urls.py
+++ b/django_rest/test_app/urls.py
@@ -1,5 +1,5 @@
 """
-Urls for Django v4.1 test project app.
+Urls for Django REST test project app.
 """
 
 # Third-Party Imports.
diff --git a/django_rest/test_app/views.py b/django_rest/test_app/views.py
index 5437a2a..a9546d0 100644
--- a/django_rest/test_app/views.py
+++ b/django_rest/test_app/views.py
@@ -8,15 +8,22 @@ import html
 import requests
 
 # Third-Party Imports.
+from django.contrib.auth import get_user_model
 from django.contrib.auth.decorators import login_required, permission_required
+from django.contrib.auth.models import Group
 from django.http import HttpResponse, JsonResponse, QueryDict
 from django.views.decorators.csrf import csrf_exempt
 from django.views.decorators.http import require_http_methods
 from django.shortcuts import redirect, render, reverse
+from rest_framework import permissions, viewsets
 
 # Internal Imports.
 from test_app.forms import ApiSendForm
 from test_app.models import ApiRequestJson
+from test_app.serializers import (
+    GroupSerializer,
+    UserSerializer,
+)
 
 
 # region Index/Root Views
@@ -254,3 +261,25 @@ def api_send(request):
     })
 
 # endregion API Views
+
+
+# region REST API Views
+
+class UserModelViewSet(viewsets.ModelViewSet):
+    """
+    API endpoint that allows users to be viewed or edited.
+    """
+    queryset = get_user_model().objects.all().order_by('-date_joined')
+    serializer_class = UserSerializer
+    permission_classes = [permissions.IsAuthenticated]
+
+
+class GroupModelViewSet(viewsets.ModelViewSet):
+    """
+    API endpoint that allows groups to be viewed or edited.
+    """
+    queryset = Group.objects.all()
+    serializer_class = GroupSerializer
+    permission_classes = [permissions.IsAuthenticated]
+
+# endregion REST API Views
-- 
GitLab