77from django .contrib .admin .widgets import SELECT2_TRANSLATIONS , AutocompleteMixin
88from django .contrib .contenttypes .models import ContentType
99from django .contrib .sites .models import Site
10- from django .core .exceptions import ObjectDoesNotExist , ValidationError
10+ from django .core .exceptions import ObjectDoesNotExist
1111from django .db import models
12- from django .db .models .fields .related import ManyToOneRel
13- from django .utils .encoding import force_str
1412from django .utils .translation import get_language
1513from django .utils .translation import gettext as _
14+ from djangocms_link .fields import LinkFormField
1615
1716# from djangocms_link.validators import IntranetURLValidator
1817from entangled .forms import EntangledModelForm
19- from filer .fields .image import AdminFileFormField , FilerFileField
20- from filer .models import File
2118
2219from ... import settings
2320from ...common import SpacingFormMixin
2825 TagTypeFormField ,
2926 TemplateChoiceMixin ,
3027)
31- from ...helpers import first_choice , get_related_object
28+ from ...helpers import first_choice
3229from ...models import FrontendUIItem
3330from .. import link
3431from .constants import LINK_CHOICES , LINK_SIZE_CHOICES , TARGET_CHOICES
35- from .helpers import get_choices , get_object_for_value
32+ from .helpers import get_object_for_value
3633
3734mixin_factory = settings .get_forms (link )
3835
@@ -174,59 +171,18 @@ class AbstractLinkForm(EntangledModelForm):
174171 class Meta :
175172 entangled_fields = {
176173 "config" : [
177- "external_link" ,
178- "internal_link" ,
179- "file_link" ,
180- "anchor" ,
181- "mailto" ,
182- "phone" ,
174+ "link" ,
183175 "target" ,
184176 ]
185177 }
186178
187179 link_is_optional = False
188180
189- # url_validators = [
190- # IntranetURLValidator(intranet_host_re=HOSTNAME),
191- # ]
192-
193- external_link = forms .URLField (
194- label = _ ("External link" ),
195- required = False ,
196- # validators=url_validators,
197- help_text = _ ("Provide a link to an external source." ),
198- )
199- internal_link = SmartLinkField (
200- label = _ ("Internal link" ),
201- required = False ,
202- help_text = _ ("If provided, overrides the external link." ),
203- )
204- file_link = AdminFileFormField (
205- rel = ManyToOneRel (FilerFileField , File , "id" ),
206- queryset = File .objects .all (),
207- to_field_name = "id" ,
208- label = _ ("File link" ),
181+ link = LinkFormField (
182+ label = _ ("Link" ),
183+ initial = {},
209184 required = False ,
210- help_text = _ ("If provided links a file from the filer app." ),
211185 )
212- # other link types
213- anchor = forms .CharField (
214- label = _ ("Anchor" ),
215- required = False ,
216- help_text = _ (
217- "Appends the value only after the internal or external link. "
218- 'Do <em>not</em> include a preceding "#" symbol.'
219- ),
220- )
221- mailto = forms .EmailField (
222- label = _ ("Email address" ),
223- required = False ,
224- )
225- phone = forms .CharField (
226- label = _ ("Phone" ),
227- required = False ,
228- )
229- # advanced options
230186 target = forms .ChoiceField (
231187 label = _ ("Target" ),
232188 choices = settings .EMPTY_CHOICE + TARGET_CHOICES ,
@@ -235,71 +191,7 @@ class Meta:
235191
236192 def __init__ (self , * args , ** kwargs ):
237193 super ().__init__ (* args , ** kwargs )
238- self .fields ["internal_link" ].choices = self .get_choices
239-
240- def get_choices (self ):
241- if MINIMUM_INPUT_LENGTH == 0 :
242- return get_choices (self .request )
243- if not self .is_bound : # find initial value
244- int_link_field = self .fields ["internal_link" ]
245- initial = self .get_initial_for_field (int_link_field , "internal_link" )
246- if initial : # Initial set?
247- obj = get_related_object (dict (obj = initial ), "obj" ) # get it!
248- if obj is not None :
249- value = int_link_field .prepare_value (initial )
250- return ((value , str (obj )),)
251- return () # nothing found
252-
253- def clean (self ):
254- super ().clean ()
255- link_field_names = (
256- "external_link" ,
257- "internal_link" ,
258- "mailto" ,
259- "phone" ,
260- "file_link" ,
261- )
262- anchor_field_name = "anchor"
263- field_names_allowed_with_anchor = (
264- "external_link" ,
265- "internal_link" ,
266- )
267- anchor_field_verbose_name = force_str (self .fields [anchor_field_name ].label )
268- anchor_field_value = self .cleaned_data .get (anchor_field_name , None )
269- link_fields = {key : self .cleaned_data .get (key , None ) for key in link_field_names }
270- link_field_verbose_names = {key : force_str (self .fields [key ].label ) for key in link_fields .keys ()}
271- provided_link_fields = {key : value for key , value in link_fields .items () if value }
272-
273- if len (provided_link_fields ) > 1 :
274- # Too many fields have a value.
275- verbose_names = sorted (link_field_verbose_names .values ())
276- error_msg = _ ("Only one of {0} or {1} may be given." ).format (
277- ", " .join (verbose_names [:- 1 ]),
278- verbose_names [- 1 ],
279- )
280- errors = {}.fromkeys (provided_link_fields .keys (), error_msg )
281- raise ValidationError (errors )
282-
283- if (
284- len (provided_link_fields ) == 0
285- and not self .cleaned_data .get (anchor_field_name , None )
286- and not self .link_is_optional
287- ):
288- raise ValidationError (_ ("Please provide a link." ))
289-
290- if anchor_field_value :
291- for field_name in provided_link_fields .keys ():
292- if field_name not in field_names_allowed_with_anchor :
293- error_msg = _ ("%(anchor_field_verbose_name)s is not allowed together with %(field_name)s" ) % {
294- "anchor_field_verbose_name" : anchor_field_verbose_name ,
295- "field_name" : link_field_verbose_names .get (field_name ),
296- }
297- raise ValidationError (
298- {
299- anchor_field_name : error_msg ,
300- field_name : error_msg ,
301- }
302- )
194+ self .fields ["link" ].required = not self .link_is_optional
303195
304196
305197class LinkForm (mixin_factory ("Link" ), SpacingFormMixin , TemplateChoiceMixin , AbstractLinkForm ):
0 commit comments