0
app/api/__init__.py
Normal file
0
app/api/__init__.py
Normal file
6
app/api/apps.py
Normal file
6
app/api/apps.py
Normal file
@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ApiConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'api'
|
30
app/api/serializers/access.py
Normal file
30
app/api/serializers/access.py
Normal file
@ -0,0 +1,30 @@
|
||||
from rest_framework import serializers
|
||||
from access.models import Organization, Team
|
||||
|
||||
|
||||
class TeamSerializer(serializers.ModelSerializer):
|
||||
|
||||
|
||||
class Meta:
|
||||
model = Team
|
||||
fields = (
|
||||
"group_ptr_id",
|
||||
"name",
|
||||
)
|
||||
|
||||
|
||||
|
||||
class OrganizationSerializer(serializers.ModelSerializer):
|
||||
|
||||
url = serializers.HyperlinkedIdentityField(
|
||||
view_name="_api_organization", format="html"
|
||||
)
|
||||
|
||||
|
||||
class Meta:
|
||||
model = Organization
|
||||
fields = (
|
||||
"id",
|
||||
"name",
|
||||
'url',
|
||||
)
|
16
app/api/urls.py
Normal file
16
app/api/urls.py
Normal file
@ -0,0 +1,16 @@
|
||||
from django.urls import path
|
||||
from rest_framework.urlpatterns import format_suffix_patterns
|
||||
|
||||
from .views import access, index
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("", index.IndexView.as_view(), name='_api_home'),
|
||||
path("organization/", access.OrganizationList.as_view(), name='_api_orgs'),
|
||||
path("organization/<int:pk>/", access.OrganizationDetail.as_view(), name='_api_organization'),
|
||||
path("organization/<int:organization_id>/team/<int:group_ptr_id>/", access.TeamDetail.as_view(), name='_api_team'),
|
||||
path("organization/team/", access.TeamList.as_view(), name='_api_teams'),
|
||||
|
||||
]
|
||||
|
||||
urlpatterns = format_suffix_patterns(urlpatterns)
|
42
app/api/views/access.py
Normal file
42
app/api/views/access.py
Normal file
@ -0,0 +1,42 @@
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
|
||||
|
||||
from rest_framework import generics
|
||||
|
||||
from access.models import Organization, Team
|
||||
from api.serializers.access import OrganizationSerializer, TeamSerializer
|
||||
|
||||
|
||||
|
||||
class OrganizationList(PermissionRequiredMixin, LoginRequiredMixin, generics.ListCreateAPIView):
|
||||
permission_required = 'access.view_organization'
|
||||
queryset = Organization.objects.all()
|
||||
serializer_class = OrganizationSerializer
|
||||
|
||||
|
||||
def get_view_name(self):
|
||||
return "Organizations"
|
||||
|
||||
|
||||
|
||||
class OrganizationDetail(PermissionRequiredMixin, LoginRequiredMixin, generics.RetrieveUpdateDestroyAPIView):
|
||||
permission_required = 'access.view_organization'
|
||||
queryset = Organization.objects.all()
|
||||
serializer_class = OrganizationSerializer
|
||||
|
||||
|
||||
def get_view_name(self):
|
||||
return "Organization"
|
||||
|
||||
|
||||
|
||||
class TeamList(generics.ListCreateAPIView):
|
||||
queryset = Team.objects.all()
|
||||
serializer_class = TeamSerializer
|
||||
|
||||
|
||||
|
||||
class TeamDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
queryset = Team.objects.all()
|
||||
serializer_class = TeamSerializer
|
||||
|
||||
lookup_field = 'group_ptr_id'
|
33
app/api/views/index.py
Normal file
33
app/api/views/index.py
Normal file
@ -0,0 +1,33 @@
|
||||
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
|
||||
from django.contrib.auth.models import User
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
from rest_framework import generics, permissions, routers
|
||||
from rest_framework.decorators import api_view
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.reverse import reverse
|
||||
|
||||
|
||||
|
||||
class IndexView(PermissionRequiredMixin, LoginRequiredMixin, routers.APIRootView):
|
||||
|
||||
permission_required = 'access.view_organization'
|
||||
|
||||
def get_view_name(self):
|
||||
return "My API"
|
||||
|
||||
def get_view_description(self, html=False) -> str:
|
||||
text = "My REST API"
|
||||
if html:
|
||||
return mark_safe(f"<p>{text}</p>")
|
||||
else:
|
||||
return text
|
||||
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
return Response(
|
||||
{
|
||||
"organizations": reverse("_api_orgs", request=request),
|
||||
"teams": reverse("_api_teams", request=request),
|
||||
}
|
||||
)
|
@ -38,6 +38,8 @@ INSTALLED_APPS = [
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
'rest_framework',
|
||||
'rest_framework_json_api',
|
||||
'social_django',
|
||||
'core.apps.CoreConfig',
|
||||
'access.apps.AccessConfig',
|
||||
@ -153,4 +155,36 @@ STATICFILES_DIRS = [
|
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||||
|
||||
SITE_TITLE = "Site Title"
|
||||
SITE_TITLE = "Site Title"
|
||||
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'PAGE_SIZE': 10,
|
||||
'EXCEPTION_HANDLER': 'rest_framework_json_api.exceptions.exception_handler',
|
||||
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||
'rest_framework.authentication.SessionAuthentication',
|
||||
],
|
||||
'DEFAULT_PAGINATION_CLASS':
|
||||
'rest_framework_json_api.pagination.JsonApiPageNumberPagination',
|
||||
'DEFAULT_PARSER_CLASSES': (
|
||||
'rest_framework_json_api.parsers.JSONParser',
|
||||
'rest_framework.parsers.FormParser',
|
||||
'rest_framework.parsers.MultiPartParser'
|
||||
),
|
||||
'DEFAULT_RENDERER_CLASSES': (
|
||||
'rest_framework_json_api.renderers.JSONRenderer',
|
||||
'rest_framework_json_api.renderers.BrowsableAPIRenderer',
|
||||
),
|
||||
'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',
|
||||
'DEFAULT_FILTER_BACKENDS': (
|
||||
'rest_framework_json_api.filters.QueryParameterValidationFilter',
|
||||
'rest_framework_json_api.filters.OrderingFilter',
|
||||
'rest_framework_json_api.django_filters.DjangoFilterBackend',
|
||||
'rest_framework.filters.SearchFilter',
|
||||
),
|
||||
'SEARCH_PARAM': 'filter[search]',
|
||||
'TEST_REQUEST_RENDERER_CLASSES': (
|
||||
'rest_framework_json_api.renderers.JSONRenderer',
|
||||
),
|
||||
'TEST_REQUEST_DEFAULT_FORMAT': 'vnd.api+json'
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ from .views import HomeView
|
||||
|
||||
urlpatterns = [
|
||||
path('', HomeView.as_view(), name='home'),
|
||||
path("api/", include("api.urls")),
|
||||
path('admin/', admin.site.urls, name='_administration'),
|
||||
path('account/password_change/', auth_views.PasswordChangeView.as_view(template_name="password_change.html.j2"),
|
||||
name="change_password"),
|
||||
|
@ -1,3 +1,10 @@
|
||||
Django==5.0.4
|
||||
Django==5.0.6
|
||||
django-debug-toolbar==4.3.0
|
||||
social-auth-app-django==5.4.1
|
||||
|
||||
djangorestframework==3.15.1
|
||||
djangorestframework-jsonapi==7.0.0
|
||||
|
||||
# DRF
|
||||
pyyaml==6.0.1
|
||||
django-filter==24.2
|
Reference in New Issue
Block a user