@@ -83,12 +83,12 @@ def _setup_form_fields(self):
8383
8484 # Handle name
8585 self .fields ["name" ].initial = ""
86- # Initialize the tags field to existing tags or empty list
87- if self .instance and self .instance .pk and hasattr (self .instance , "tags " ):
86+ # Initialize subjects_keywords field to existing JSON data or empty list
87+ if self .instance and self .instance .pk and hasattr (self .instance , "subjects_keywords " ):
8888 self .instance .refresh_from_db ()
89- self ._original_tags = list ( self .instance .tags . all ())
89+ self ._original_subjects_keywords = self .instance .subjects_keywords or []
9090 else :
91- self ._original_tags = []
91+ self ._original_subjects_keywords = []
9292
9393 self ._restore_model_help_text ()
9494
@@ -243,9 +243,44 @@ def clean_note_on_linkonly_privacy(self):
243243
244244 return note_on_linkonly_privacy
245245
246- def clean_tags (self ):
247- cleaned_data = super ().clean ()
248- return cleaned_data .get ("tags" , [])
246+ def clean_subjects_keywords (self ):
247+ raw = self .cleaned_data .get ("subjects_keywords" ) or []
248+
249+ if isinstance (raw , str ):
250+ try :
251+ raw = json .loads (raw )
252+ except json .JSONDecodeError as e :
253+ raise forms .ValidationError ("Invalid subjects/keywords data." ) from e
254+
255+ if not isinstance (raw , list ):
256+ raise forms .ValidationError ("Subjects/keywords must be a list." )
257+
258+ cleaned_subjects_keywords = []
259+
260+ for item in raw :
261+ if not isinstance (item , dict ):
262+ raise forms .ValidationError ("Each subject/keyword entry must be an object." )
263+
264+ subject = (item .get ("subject" ) or "" ).strip ()
265+ subject_scheme = (item .get ("subject_scheme" ) or "" ).strip ()
266+ classification_code = (item .get ("classification_code" ) or "" ).strip ()
267+
268+ if not subject :
269+ raise forms .ValidationError ("Each subject/keyword entry must have a subject." )
270+ if not subject_scheme :
271+ raise forms .ValidationError ("Each subject/keyword entry must have a scheme." )
272+ if not classification_code :
273+ raise forms .ValidationError ("Each subject/keyword entry must have an identifier." )
274+
275+ cleaned_subjects_keywords .append (
276+ {
277+ "subject" : subject ,
278+ "subject_scheme" : subject_scheme ,
279+ "classification_code" : classification_code ,
280+ }
281+ )
282+
283+ return cleaned_subjects_keywords
249284
250285 def clean_funding_sources_json (self ):
251286 raw = self .cleaned_data .get ("funding_sources_json" ) or "[]"
@@ -372,26 +407,28 @@ def normalize(data):
372407 # If there's an error, keep the field in changed_data to be safe
373408 pass
374409
375- # Handle tags field - compare current input with initial tags
376- if "tags " in changed_data and self .instance and self .instance .pk :
410+ # Handle subjects_keywords field - compare JSON data
411+ if "subjects_keywords " in changed_data and self .instance and self .instance .pk :
377412 try :
378- # Try invenio_tags field first, then tags field
379- current_tags_input = self .data .get ("invenio_tags" , "" ) or self .data .get ("tags" , "" ) or ""
380- initial_tags_input = None
381-
382- if "invenio_tags" in self .fields :
383- initial_tags_input = self .fields ["invenio_tags" ].initial or ""
384- elif hasattr (self , "_original_tags" ) and self ._original_tags :
385- # Fallback to database tags formatted as pipe-separated
386- initial_tags_input = " | " .join (str (tag ) for tag in self ._original_tags )
387- else :
388- initial_tags_input = ""
413+ current_subjects_keywords = self .data .get ("subjects_keywords" , "" ) or "[]"
414+ initial_subjects_keywords = self .fields ["subjects_keywords" ].initial or "[]"
389415
390- # If the tag input is the same, remove from changed_data
391- if current_tags_input == initial_tags_input :
392- changed_data .remove ("tags" )
393- except (AttributeError , KeyError ):
394- # If there's an error, keep the field in changed_data to be safe
416+ current_data = (
417+ json .loads (current_subjects_keywords )
418+ if isinstance (current_subjects_keywords , str )
419+ else current_subjects_keywords
420+ )
421+ initial_data = (
422+ json .loads (initial_subjects_keywords )
423+ if isinstance (initial_subjects_keywords , str )
424+ else initial_subjects_keywords
425+ )
426+
427+ # If the data is the same, remove from changed_data
428+ if current_data == initial_data :
429+ changed_data .remove ("subjects_keywords" )
430+ except (json .JSONDecodeError , KeyError , ValueError , TypeError ):
431+ # If there's an error parsing, keep the field in changed_data to be safe
395432 pass
396433
397434 # Handle language field - compare current value with initial form value
0 commit comments