
    h!                        d dl Z d dlZd dlmZ d dlmZ d dlmZmZ d dl	m
Z
 d dlmZ d dlmZmZ d dlmZ d	d
lmZ  e
dej*                  d      Zg dZ G d dej0                        Z G d dej4                        Zy)    N)partial)forms)ImproperlyConfiguredValidationError)RegexValidator)models)conditional_escape	mark_safe)gettext_lazy   )AttributesWidgetz^[a-z][-a-z0-9_:]*\Zinvalid)regexflagscode)srchrefdataactionzon*c                   >     e Zd ZddgZ fdZd Zd Zd Zd Z xZ	S )AttributesFormFieldN c                     |j                  dt               |j                  dg       t        z   | _        t        |   |i | y )Nwidgetexcluded_keys)
setdefaultr   popdefault_excluded_keysr   super__init__)selfargskwargs	__class__s      Q/home/dcms/DCMS/lib/python3.12/site-packages/djangocms_attributes_field/fields.pyr    zAttributesFormField.__init__   s?    ($45#ZZ<?TT$)&)    c           	          t        |t              r|r	 t        j                  |      S |S # t        $ r?}t        j                  dj                  t        |j                  d                     d }~ww xY w)NzJSON decode error: {}r   )	
isinstancestrjsonloads
ValueErrorr   r   formatr"   )r!   valueexcs      r%   	to_pythonzAttributesFormField.to_python   si    eS!ezz%(( L  +++223sxx{3CD s   + 	A3:A..A3c                    || j                   v r0| j                  r$t        j                  | j                  d   d      t        |t              r<|j                         D ](  \  }}| j                  |       | j                  ||       * y y )Nrequired)r   )
empty_valuesr2   r   r   error_messagesr(   dictitemsvalidate_keyvalidate_value)r!   r.   keyvals       r%   validatezAttributesFormField.validate(   sz    D%%%$--''(;(;J(GjYYeT"!KKM .S!!#&##C-. #r&   c                 v   | j                   D ]m  }|j                         |k(  s5|j                  d      s(|j                         j                  |dd       sKt	        t        d      j                  |             	 t        |       y# t        $ r% t	        t        d      j                  |            w xY w)a  
        A key must start with a letter, but can otherwise contain letters,
        numbers, dashes, colons or underscores. It must not also be part of
        `excluded_keys` as configured in the field.

        :param key: (str) The key to validate
        *NzA"{key}" is excluded by configuration and cannot be used as a key.r9   z"{key}" is not a valid key. Keys must start with at least one letter and consist only of the letters, numbers, underscores or hyphens.)r   lowerendswith
startswithr   _r-   regex_key_validator)r!   r9   excluded_keys      r%   r7   z AttributesFormField.validate_key1   s     !.. 	1Lyy{l*l.C.CC.HSYY[McMcdpqtrtduMv%    &31 1	1	>$ 	> " , --3VV_> >	>s   >B
 
.B8c                     	 t        j                  |       y# t        t        f$ r% t	        t        d      j                  |            w xY w)z
        A value can be anything that can be JSON-ified.

        :param key: (str) The key of the value
        :param value: (str) The value to validate
        z_The value for the key "{key}" is invalid. Please enter a value that can be represented in JSON.r?   N)r*   dumps	TypeErrorr,   r   rC   r-   )r!   r9   r.   s      r%   r8   z"AttributesFormField.validate_valueJ   sQ    	MJJu:& 	M! ; <<BFsFOM M	Ms	    4A)
__name__
__module____qualname__r3   r    r0   r;   r7   r8   __classcell__r$   s   @r%   r   r      s&    ":L*
	.>2Mr&   r   c                        e Zd ZdZd ed      iZdZ fdZ fdZddZ	ddZ
d	 Z fd
Zd Z fdZd Zd Zed        Z xZS )AttributesFieldaw  
    This is an opinionated sub-class of JSONField. Here's a summary of the
    primary differences:

        * Instead of storing any arbitrary JSON, we stick to a flat list of
          key/value pairs;
        * Keys must start with a letter and only contain letters, numbers,
          underscores and hyphens;
        * We accept a field parameter `excluded_keys` which contains a list
          of keys we do not accept and enforce this;
        * Validation checks for both key format and excluded_keys are done
          in a case-insensitive manner;
        * The default widget is AttributesWidget from this package.
    r   z '%s' is not a valid JSON string.zJSON objectc                 .   |j                  dd      s|j                  dt              |d<   |j                  dg       }|D cg c]  }|j                          c}| _        t        |   |i | | j                  | j                         d        y c c}w )NnullFdefaultr   )	getr5   r   r@   r   r   r    r;   get_default)r!   r"   r#   r   r9   r$   s        r%   r    zAttributesField.__init__m   s    zz&%( &

9d ;F9

?B7 6CCcciikC$)&)d&&($/ Ds   Bc                 ~    t         t        d} |j                  di | | j                  |d<   t	        |   di |S )N)
form_classr   r    )r   r   updater   r   	formfield)r!   r#   defaultsr$   s      r%   rY   zAttributesField.formfieldw   sF    -&
 	!&!$($6$6!w ,8,,r&   c                 V    |yt        |t              rt        j                  |      S |S )z
        This is a temporary workaround for #7 taken from
        https://bitbucket.org/schinckel/django-jsonfield/pull-requests/32/make-from_db_value-compatible-with/diff
        See there for full discussion
        N)r(   r)   r*   r+   )r!   r.   
expression
connections       r%   from_db_valuezAttributesField.from_db_value   s*     =s#::e$$Lr&   c                 $    | j                  |      S N)get_prep_value)r!   r.   r]   prepareds       r%   get_db_prep_valuez!AttributesField.get_db_prep_value   s    ""5))r&   c                 d    || j                   s| j                  ryy t        j                  |      S )Nr   )rQ   blankr*   rG   )r!   r.   s     r%   ra   zAttributesField.get_prep_value   s)    =99zz%  r&   c                    | j                         rk| j                  }t        |      r |       }t        |t              rt        j                  |      S t        j                  t        j                  |            S t        | %         S r`   )
has_defaultrR   callabler(   r)   r*   r+   rG   r   rT   )r!   rR   r$   s     r%   rT   zAttributesField.get_default   sf    llG !)'3'zz'**::djj122w"$$r&   c                      y)N	TextFieldrW   )r!   s    r%   get_internal_typez!AttributesField.get_internal_type   s    r&   c                     t        |   ||fi | | d}t        ||      s.t        | j                  |      }t        ||t        |             yy)u   
        Adds a @property: «name»_str that returns a string representation of
        the attributes ready for inclusion on an HTML element.
        _str
field_nameN)r   contribute_to_classhasattrr   to_strsetattrproperty)r!   clsnamer#   property_namestr_propertyr$   s         r%   rp   z#AttributesField.contribute_to_class   sT    
 	#C88&sM*"4;;4@LC(>? +r&   c                     | j                   s|t        | j                  d         	 | j                  |       y # t        $ r t        | j                  d   |z        w xY w)NrQ   r   )rQ   r   r4   ra   r,   )r!   r.   model_instances      r%   r;   zAttributesField.validate   sc    yyU]!$"5"5f"=>>	J& 	J!$"5"5i"@5"HII	Js	   : %Ac                 $    | j                  |      S r`   )value_from_object)r!   objs     r%   value_to_stringzAttributesField.value_to_string   s    %%c**r&   c                 P   t        ||      s%t        t        d      j                  ||            |j                  }|j                  |      }t        ||       s$t        t        d      j                  |            |j                  }t        ||      }	 |j                         }g }|D ]M  \  }	}
|	j                         |vs|
r!|j                  |	 dt        |
       d       <|j                  |	        O t        dj!                  |            S # t        $ r |g}Y |w xY w)z
        Emits stored attributes as a String suitable for for adding to an
        HTML element and performs an outbound filter of excluded_keys.
        z("{field_name}" is not a field of {obj|r})r}   ro   z("{field_name}" is not an AttributesFieldrn   z="" )rq   r   rC   r-   _meta	get_fieldr(   rH   r   getattrr6   AttributeErrorr@   appendr	   r
   join)ru   r}   ro   optsfieldr   r.   value_itemsattrsr9   r:   s              r%   rr   zAttributesField.to_str   s6    sJ'&<=DD
 E 45 5 yyz*%%<=DD) E +, , ++Z(	"++-K # 	+HCyy{-/LLC5+=c+B*C1!EFLLC5*	+ %))  	" 'K	"s   D D%$D%)NN)rI   rJ   rK   __doc__rC   default_error_messagesdescriptionr    rY   r^   rc   ra   rT   rk   rp   r;   r~   classmethodrr   rL   rM   s   @r%   rO   rO   Y   sl     	178  K0-*!%
@J+ &* &*r&   rO   )r*   re	functoolsr   djangor   django.core.exceptionsr   r   django.core.validatorsr   	django.dbr   django.utils.htmlr	   r
   django.utils.translationr   rC   widgetsr   
IGNORECASErD   r   	CharFieldr   FieldrO   rW   r&   r%   <module>r      sj     	   H 1  ; 6 %$+B+-==yJ  AM%// AMHI*fll I*r&   