Coverage for apis_core/generic/urls.py: 96%
27 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-09-14 10:55 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-09-14 10:55 +0000
1from django.contrib.contenttypes.models import ContentType
2from django.http import Http404
3from django.shortcuts import get_object_or_404
4from django.urls import include, path, register_converter
5from rest_framework import routers
7from apis_core.generic import api_views, views
9from .abc import GenericModel
11app_name = "generic"
14class ContenttypeConverter:
15 """
16 A converter that converts from a string representation of a
17 model (`app_label.model`) to the actual Django model class.
18 """
20 regex = r"\w+\.\w+"
22 def to_python(self, value):
23 app_label, model = value.split(".")
24 contenttype = get_object_or_404(ContentType, app_label=app_label, model=model)
25 if issubclass(contenttype.model_class(), GenericModel):
26 return contenttype
27 raise Http404
29 def to_url(self, value):
30 if isinstance(value, ContentType):
31 return f"{value.app_label}.{value.model}"
32 if isinstance(value, str):
33 return value
34 if issubclass(value, GenericModel):
35 return value._meta.label_lower
38register_converter(ContenttypeConverter, "contenttype")
40router = routers.DefaultRouter()
41router.register(r"", api_views.ModelViewSet, basename="genericmodelapi")
43urlpatterns = [
44 path("overview/", views.Overview.as_view(), name="overview"),
45 path(
46 "<contenttype:contenttype>/",
47 include(
48 [
49 path("", views.List.as_view(), name="list"),
50 path("<int:pk>", views.Detail.as_view(), name="detail"),
51 path("create", views.Create.as_view(), name="create"),
52 path("delete/<int:pk>", views.Delete.as_view(), name="delete"),
53 path("update/<int:pk>", views.Update.as_view(), name="update"),
54 path("duplicate/<int:pk>", views.Duplicate.as_view(), name="duplicate"),
55 path(
56 "selectmergeorenrich/<int:pk>",
57 views.SelectMergeOrEnrich.as_view(),
58 name="selectmergeorenrich",
59 ),
60 path(
61 "merge/<int:pk>/<int:otherpk>",
62 views.MergeWith.as_view(),
63 name="merge",
64 ),
65 path("enrich/<int:pk>", views.Enrich.as_view(), name="enrich"),
66 path("autocomplete", views.Autocomplete.as_view(), name="autocomplete"),
67 path("import", views.Import.as_view(), name="import"),
68 path(
69 "autocomplete/externalonly",
70 views.Autocomplete.as_view(),
71 {"external_only": True},
72 name="autocompleteexternalonly",
73 ),
74 ]
75 ),
76 ),
77 path("api/<contenttype:contenttype>/", include(router.urls)),
78]