diff --git a/django_rest/Pipfile b/django_rest/Pipfile index 36e8f3a0c4dfd2bb5d4697da296eea803c728885..7cb12ea26670470adbb2f61725fdc6bb64f53bc6 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 a24326052a8f4a557dcc99dacf08e0cad4e449dd..4bbc520227ab5f86ae66e517bcc1c42b4b1b881a 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 3f9b160743c5ee8b64121631b1e162f32459ea06..dba9af22f8651690f8d64d5b74df09ab3ae647d4 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 0000000000000000000000000000000000000000..1684c39b7475e46e79bbf4fa6af740f70794ebcd --- /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 0000000000000000000000000000000000000000..7003371cf4a1cb0dfd76afd56ed88fed426339d8 --- /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 e9245a2749ae48a5727cff9d38ec36dd5ca30ddc..4ac5e8febcd155cc1d9cd91ce3835501c1f730dc 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 5437a2a2244f15eebc09c9c2791166598438cbc7..a9546d0c79c54017d519ae3f002958471fa74d2c 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