1- from importlib import import_module
2-
3- from cms .forms .utils import get_page_choices
4- from cms .models import Page
51from django .apps import apps
6- from django .conf import settings as django_settings
7- from django .contrib .admin import site
82from django .contrib .contenttypes .models import ContentType
93from django .contrib .sites .models import Site
10- from django .core .exceptions import FieldError , ObjectDoesNotExist
11- from django .utils .encoding import force_str
4+ from django .core .exceptions import ObjectDoesNotExist
125
136from djangocms_frontend .helpers import get_related_object
147
15- LINK_MODELS = getattr (django_settings , "DJANGOCMS_FRONTEND_LINK_MODELS" , [])
16-
17-
18- def create_querysets (link_models ):
19- querysets = []
20- for item in link_models :
21- if item ["class_path" ] != "cms.models.Page" :
22- # CMS pages are collected using a cms function to preserve hierarchy
23- section = item ["type" ]
24- parts = item ["class_path" ].rsplit ("." , 1 )
25- cls = getattr (import_module (parts [0 ]), parts [1 ])
26- queryset = cls .objects
27-
28- if "manager_method" in item :
29- queryset = getattr (queryset , item ["manager_method" ])()
30-
31- if "filter" in item :
32- for k , v in item ["filter" ].items ():
33- try :
34- # Attempt to execute any callables in the filter dict.
35- item ["filter" ][k ] = v ()
36- except TypeError :
37- # OK, it wasn't a callable, so, leave it be
38- pass
39- queryset = queryset .filter (** item ["filter" ])
40- else :
41- if "manager_method" not in item :
42- queryset = queryset .all ()
43- if "order_by" in item :
44- queryset = queryset .order_by (item ["order_by" ])
45- querysets .append ((section , queryset , item .get ("search" , None ), cls ))
46- return querysets
47-
48-
49- _querysets = create_querysets (LINK_MODELS )
50-
518
529def get_object_for_value (value ):
5310 if isinstance (value , str ) and "-" in value :
@@ -63,81 +20,6 @@ def get_object_for_value(value):
6320 return None
6421
6522
66- def unescape (text , nbsp ):
67- return (
68- text .replace (" " , nbsp )
69- .replace ("&" , "&" )
70- .replace ("<" , "<" )
71- .replace (">" , ">" )
72- .replace (""" , '"' )
73- .replace ("'" , "'" )
74- )
75-
76-
77- def get_link_choices (request , term = "" , lang = None , nbsp = None ):
78- global _querysets
79-
80- if nbsp is None :
81- nbsp = "" if term else "\u2000 "
82- available_objects = []
83- # Now create our list of cms pages
84- type_id = ContentType .objects .get_for_model (Page ).id
85- for value , descr in get_page_choices (lang ):
86- if isinstance (descr , list ):
87- available_objects .append (
88- {
89- "text" : value ,
90- "children" : [
91- dict (
92- id = f"{ type_id } -{ page } " ,
93- # django admin's autocomplete view requires unescaped strings
94- # get_page_choices escapes strings, so we undo the escape
95- text = unescape (name , nbsp ),
96- )
97- for page , name in descr
98- if not isinstance (term , str ) or term .upper () in name .upper ()
99- ],
100- }
101- )
102- elif value and isinstance (value , int ):
103- available_objects .append (dict (id = f"{ type_id } -{ value } " ))
104-
105- # Add list of additional non-cms pages
106- for section , qs , search , cls in _querysets :
107- objects = None
108- model_admin = site ._registry .get (cls , None )
109- if search :
110- try :
111- objects = qs .filter (** {search + "__icontains" : term })
112- except FieldError :
113- pass
114- if objects is None :
115- objects = [item for item in qs .all () if (not isinstance (term , str )) or term .upper () in str (item ).upper ()]
116- if objects :
117- type_class = ContentType .objects .get_for_model (objects [0 ].__class__ )
118- available_objects .append (
119- {
120- "text" : force_str (section ),
121- "children" : [
122- dict (id = f"{ type_class .id } -{ obj .id } " , text = str (obj ))
123- for obj in objects
124- if request is None or model_admin and model_admin .has_view_permission (request , obj = obj )
125- ],
126- }
127- )
128- return available_objects
129-
130-
131- def get_choices (request , term = "" , lang = None ) -> list :
132- def to_choices (json ):
133- return list (
134- (elem ["text" ], to_choices (elem ["children" ])) if "children" in elem else (elem ["id" ], elem ["text" ])
135- for elem in json
136- )
137-
138- return to_choices (get_link_choices (request , term , lang , " " ))
139-
140-
14123class GetLinkMixin :
14224 def get_link (self ) -> str :
14325 if "url_grouper" in self .config and self .config ["url_grouper" ] and apps .is_installed ("djangocms_url_manager" ):
0 commit comments