Coverage for apis_core/generic/urls.py: 64%

25 statements  

« prev     ^ index     » next       coverage.py v7.5.3, created at 2025-06-25 10:00 +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 

6 

7from apis_core.generic import api_views, views 

8 

9from .abc import GenericModel 

10 

11app_name = "generic" 

12 

13 

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 """ 

19 

20 regex = r"\w+\.\w+" 

21 

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 

28 

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 

35 

36register_converter(ContenttypeConverter, "contenttype") 

37 

38router = routers.DefaultRouter() 

39router.register(r"", api_views.ModelViewSet, basename="genericmodelapi") 

40 

41urlpatterns = [ 

42 path("overview/", views.Overview.as_view(), name="overview"), 

43 path( 

44 "<contenttype:contenttype>/", 

45 include( 

46 [ 

47 path("", views.List.as_view(), name="list"), 

48 path("<int:pk>", views.Detail.as_view(), name="detail"), 

49 path("create", views.Create.as_view(), name="create"), 

50 path("delete/<int:pk>", views.Delete.as_view(), name="delete"), 

51 path("update/<int:pk>", views.Update.as_view(), name="update"), 

52 path("duplicate/<int:pk>", views.Duplicate.as_view(), name="duplicate"), 

53 path( 

54 "selectmergeorenrich/<int:pk>", 

55 views.SelectMergeOrEnrich.as_view(), 

56 name="selectmergeorenrich", 

57 ), 

58 path( 

59 "merge/<int:pk>/<int:otherpk>", 

60 views.MergeWith.as_view(), 

61 name="merge", 

62 ), 

63 path("enrich/<int:pk>", views.Enrich.as_view(), name="enrich"), 

64 path("autocomplete", views.Autocomplete.as_view(), name="autocomplete"), 

65 path("import", views.Import.as_view(), name="import"), 

66 path( 

67 "autocomplete/externalonly", 

68 views.Autocomplete.as_view(), 

69 {"external_only": True}, 

70 name="autocompleteexternalonly", 

71 ), 

72 ] 

73 ), 

74 ), 

75 path("api/<contenttype:contenttype>/", include(router.urls)), 

76]