
    >Tf                        d dl Z d dlZd dlZd dlmZmZ d dlZd dl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 d d	lmZ d d
lmZ d dlmZ d dlmZ d dlT 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) d dl*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 d dl5m6Z6 d dl7m8Z8m9Z9m:Z:m;Z; d dl<m=Z= d dl>m?Z? d dl@mAZA dZBeCjD        e%jE        eCjF        e%jE        eCjG        e%jH        eCjI        e%jJ        eCjK        e%jE        eCjL        e%jE        iZM G d dejN        O                    e=                    ZP G d de"e#e           ZQ G d d e"e#e           ZRdS )!    N)datetimedate)forms)settings)
ArrayField)RegexValidatorValidationError)models)reverse)escape)	mark_safe)gettext_lazy)
ObjectType)*)CHOICE_SETS)ChangeLoggedModel)CloningMixinExportTemplatesMixin)
FieldTypes)filters)datetime_from_timestamp)
CSVChoiceFieldCSVModelChoiceFieldCSVModelMultipleChoiceFieldCSVMultipleChoiceFieldDynamicChoiceFieldDynamicModelChoiceFieldDynamicModelMultipleChoiceFieldDynamicMultipleChoiceField	JSONFieldLaxURLField)add_blank_choice)	APISelectAPISelectMultiple
DatePickerDateTimePicker)RestrictedQuerySet)render_markdown)validate_regex)CustomFieldCustomFieldChoiceSetCustomFieldManagerc                       e Zd ZdZd Zd ZdS )r,   Tc                     t           j                            |j        j                  }|                                                     |          S )zF
        Return all CustomFields assigned to the given model.
        )object_types)r   objectsget_for_model_metaconcrete_modelget_querysetfilter)selfmodelcontent_types      ?/var/www/html/netbox-4.1.3/netbox/extras/models/customfields.pyr1   z CustomFieldManager.get_for_model6   sB     ")778RSS  ""))|)DDD    c                 l    |                      |                              d          }d |D             S )zv
        Return a dictionary of serialized default values for all CustomFields applicable to the given model.
        F)default__isnullc                 (    i | ]}|j         |j        S  )namedefault).0cfs     r9   
<dictcomp>z=CustomFieldManager.get_defaults_for_model.<locals>.<dictcomp>B   s+     
 
 
$&BGRZ
 
 
r:   )r1   r5   )r6   r7   custom_fieldss      r9   get_defaults_for_modelz)CustomFieldManager.get_defaults_for_model=   sI     **511888OO
 
*7
 
 
 	
r:   N)__name__
__module____qualname__use_in_migrationsr1   rE   r>   r:   r9   r,   r,   3   s;        E E E
 
 
 
 
r:   r,   c                       e Zd Z ej        dd ed                    Z ej         ed          deej	         ed                    Z
 ej        dej        d	d	 ed
                    Z ej         ed          dd	 ed           ed ed          ej                   ed ed          ej        d	          f          Z ej         ed          dd	 ed                    Z ej         ed          dd	 ed                    Z ej         ed          dd	          Z ej         ed          d ed                     Z ej         ed!          d ed"                     Z ej         ed#          d$ ed%                     Z ej         ed&          deej         ed'                    Z ej         ed(          d	d	 ed)          *          Z ej        d	d	 ed+          ,          Z ej        d- ed.           ed/          0          Z  ej!        d	d	 ed1           ed2          3          Z" ej!        d	d	 ed4           ed5          3          Z# ej        d	e$gd6 ed7           ed8          9          Z% ej        d:ej        d; ed<          d	d	=          Z& ej        de'e'j(         ed>           ed?          @          Z) ej        de*e*j+         edA           edB          @          Z, ej        d edC           edD          0          Z- ej.         edE          d	F          Z/ e0            Z1dGZ2 G dH dI          Z3dJ Z4dK Z5e6dL             Z7 fdMZ8e6dN             Z9e6dO             Z:dP Z;dQ Z<dR Z=dS Z>dT Z?dU Z@ fdVZAdW ZBdX ZCd]dYZDd^d[ZEd\ ZF xZGS )_r*   zcore.ObjectTyperD   z*The object(s) to which this field applies.)torelated_name	help_texttype2   z(The type of data this custom field holds)verbose_name
max_lengthchoicesr@   rM   Tz@The type of NetBox object this field maps to (for object fields))rK   	on_deleteblanknullrM   r?   zInternal field namez^[a-z0-9_]+$z9Only alphanumeric characters and underscores are allowed.)regexmessageflags__z;Double underscores are not permitted in custom field names.)rV   rW   rX   inverse_match)rP   rQ   uniquerM   
validatorslabelzYName of the field as displayed to users (if not provided, 'the field's name will be used))rP   rQ   rT   rM   z
group namez>Custom fields within the same group will be displayed togetherdescription   )rP   rQ   rT   requiredFzOThis field is required when creating new objects or editing an existing object.)rP   r@   rM   zmust be uniquez>The value of this field must be unique for the assigned objectzsearch weighti  zvWeighting for search. Lower values are considered more important. Fields with a search weight of zero will be ignored.zfilter logiczMLoose matches any instance of a given string; exact matches the entire field.r@   zhDefault value for the field (must be a JSON value). Encapsulate strings with double quotes (e.g. "Foo").)rP   rT   rU   rM   zFilter the object selection choices using a query_params dict (must be a JSON value).Encapsulate strings with double quotes (e.g. "Foo").)rT   rU   rM   d   zdisplay weightz2Fields with higher weights appear lower in a form.)r@   rP   rM   zminimum valuez*Minimum allowed value (for numeric fields))rT   rU   rP   rM   zmaximum valuez*Maximum allowed value (for numeric fields)i  zvalidation regexzRegular expression to enforce on text field values. Use ^ and $ to force matching of entire string. For example, <code>^[A-Z]{3}$</code> will limit values to exactly three uppercase letters.)rT   r\   rQ   rP   rM   r+   choices_forz
choice set)rK   rS   rL   rP   rT   rU   z
UI visiblez9Specifies whether the custom field is displayed in the UI)rQ   rR   r@   rP   rM   zUI editablez@Specifies whether the custom field value can be edited in the UIzis cloneablez)Replicate this value when cloning objectscomments)rP   rT   )r/   rN   related_object_type
group_namer^   r`   r[   search_weightfilter_logicr@   weightvalidation_minimumvalidation_maximumvalidation_regex
choice_set
ui_visibleui_editableis_cloneablec                   B    e Zd Zg dZ ed          Z ed          ZdS )CustomField.Meta)re   rh   r?   zcustom fieldzcustom fieldsNrF   rG   rH   ordering_rP   verbose_name_pluralr>   r:   r9   Metarq      s:        333q((a00r:   rv   c                 j    | j         p,| j                            dd                                          S )Nrt    )r]   r?   replace
capitalizer6   s    r9   __str__zCustomField.__str__   s-    zETY..sC88CCEEEr:   c                 0    t          d| j        g          S )Nzextras:customfieldargsr   pkr{   s    r9   get_absolute_urlzCustomField.get_absolute_url   s    +47)<<<<r:   c                      t           j         dS )Nzdocs/models/extras/customfield/)r   
STATIC_URLr{   s    r9   docs_urlzCustomField.docs_url   s    %FFFFr:   c                 x     t                      j        |i | | j                            d          | _        d S )Nr?   )super__init____dict__get_namer6   r   kwargs	__class__s      r9   r   zCustomField.__init__   s<    $)&))) ]&&v..


r:   c                 @    t                               | j                  S N)SEARCH_TYPESr   rN   r{   s    r9   search_typezCustomField.search_type  s    	***r:   c                 ,    | j         r| j         j        S g S r   )rl   rR   r{   s    r9   rR   zCustomField.choices  s    ? 	+?**	r:   c                 J    t           j                            | j                  S r   )CustomFieldUIVisibleChoicescolorsr   rm   r{   s    r9   get_ui_visible_colorz CustomField.get_ui_visible_color  s    *155doFFFr:   c                 J    t           j                            | j                  S r   )CustomFieldUIEditableChoicesr   r   rn   r{   s    r9   get_ui_editable_colorz!CustomField.get_ui_editable_color  s    +266t7GHHHr:   c                     t          | d          st          | j                  | _        | j                            ||          S )N_choice_map)hasattrdictrR   r   r   r6   values     r9   get_choice_labelzCustomField.get_choice_label  s?    t]++ 	2#DL11D##E5111r:   c                     |D ]f}|                                 } |j        j        di d| j        i}|D ]}| j        |j        | j        <   |j                            |dgd           gdS )z
        Populate initial custom field data upon either a) the creation of a new CustomField, or
        b) the assignment of an existing CustomField to new object types.
        custom_field_data__containscustom_field_datara   
batch_sizeNr>   )model_classr0   excluder?   r@   r   bulk_updater6   content_typesctr7   	instancesinstances         r9   populate_initial_dataz!CustomField.populate_initial_data  s    
   	X 	XBNN$$E--\\1OQUQZ0[\\I% E E8<*4955M%%i2E1FSV%WWWW	X 	Xr:   c                     |D ]h}|                                 x}rP|j                            | j                  }|D ]}|j        | j        = |j                            |dgd           idS )z
        Delete custom field data which is no longer relevant (either because the CustomField is
        no longer assigned to a model, or because it has been deleted).
        )custom_field_data__has_keyr   ra   r   N)r   r0   r5   r?   r   r   r   s         r9   remove_stale_datazCustomField.remove_stale_data#  s    
   	\ 	\B(((u \!M00DI0VV	 ) > >H 249==)))6I5JWZ)[[[	\ 	\r:   c                 $   | j                                         D ]u}|                                }d| ddi} |j        j        di |}|D ]$}|j                            |          |j        |<   %|j                            |dgd           vdS )	z_
        Called when a CustomField has been renamed. Updates all assigned object data.
        custom_field_data____isnullFr   ra   r   Nr>   )r/   allr   r0   r5   r   popr   )r6   old_namenew_namer   r7   paramsr   r   s           r9   rename_object_datazCustomField.rename_object_data/  s     #'')) 	X 	XBNN$$E>H>>>FF,,66v66I% ` `7?7Q7U7UV^7_7_*844M%%i2E1FSV%WWWW	X 	Xr:   c                 r   t                                                       | j        	 | j        t          j        t          j        fv rt          | j                  }n| j        }|                     |           nO# t          $ rB}t          dt          d                              | j        |j                  i          d }~ww xY w| j        t          j        t          j        fvrJ| j        rt          dt          d          i          | j        rt          dt          d          i          t          j        t          j        t          j        f}| j        r'| j        |vrt          dt          d	          i          | j        r3| j        t          j        k    rt          d
t          d          i          | j        t          j        t          j        fv r&| j        st          dt          d          i          n%| j        rt          dt          d          i          | j        t          j        t          j        fv r&| j        st          dt          d          i          nK| j        rDt          dt          d                              |                                           i          | j        v| j        t          j        t          j        fvrt          dt          d          i          t          | j                  t:          ur t          dt          d          i          d S d S )Nr@   z(Invalid default value "{value}": {error})r   errorri   z2A minimum value may be set only for numeric fieldsrj   z2A maximum value may be set only for numeric fieldsrk   zGRegular expression validation is supported only for text and URL fieldsr[   z0Uniqueness cannot be enforced for boolean fieldsrl   z/Selection fields must specify a set of choices.z,Choices may be set only on selection fields.rd   z)Object fields must define an object type.rN   z,{type} fields may not define an object type.rN   related_object_filterz>A related object filter can be defined only for object fields.zDFilter must be defined as a dictionary mapping attributes to values.)r   cleanr@   rN   CustomFieldTypeChoices	TYPE_TEXTTYPE_LONGTEXTstrvalidater	   rt   formatrW   TYPE_INTEGERTYPE_DECIMALri   rj   TYPE_URLrk   r[   TYPE_BOOLEANTYPE_SELECTTYPE_MULTISELECTrl   TYPE_OBJECTTYPE_MULTIOBJECTrd   get_type_displayr   r   )r6   default_valueerrregex_typesr   s       r9   r   zCustomField.clean;  s    <#9!7!ACYCg hhh$'$5$5MM$(LMm,,,,"   %qB   f4<s{fCC'    93@BXBefff& w%';Q?s=t=t&uvvv& w%';Q?s=t=t&uvvv #,"0"+

   	TYk%A%A!"A&o$p$p#   
 ; 	49(>(KKK!!NOO#   
 9&2&7
 
 
 ? % !$U"V"V'    _ 	!a NOO#   
 9/;=S=deee+ %)1-X+Y+Y'    % 	!HIIQQW[WlWlWnWnQoo#   
 %1y!7!CE[El mmm%+Q/o-p-p'    D.//t;;%+Q/u-v-v'    21
 <;s   AA; ;
C=CCc                    ||S | j         t          j        k    r*t          |          t          u r|                                S | j         t          j        k    r*t          |          t          u r|                                S | j         t          j        k    r|j        S | j         t          j	        k    rd |D             pdS |S )z;
        Prepare a value for storage as JSON data.
        Nc                     g | ]	}|j         
S r>   r   )rA   objs     r9   
<listcomp>z)CustomField.serialize.<locals>.<listcomp>  s    ,,,sCF,,,r:   )
rN   r   	TYPE_DATEr   	isoformatTYPE_DATETIMEr   r   r   r   r   s     r9   	serializezCustomField.serialize  s     =L9.888T%[[D=P=P??$$$9.<<<ePXAXAX??$$$9.:::8O9.???,,e,,,44r:   c                 F   ||S | j         t          j        k    r'	 t          j        |          S # t
          $ r |cY S w xY w| j         t          j        k    r'	 t          j        |          S # t
          $ r |cY S w xY w| j         t          j        k    rF| j	        
                                }|j                            |                                          S | j         t          j        k    r4| j	        
                                }|j                            |          S |S )zS
        Convert JSON data to a Python object suitable for the field type.
        Nr   )pk__in)rN   r   r   r   fromisoformat
ValueErrorr   r   r   rd   r   r0   r5   firstr   )r6   r   r7   s      r9   deserializezCustomField.deserialize  s1    =L9.888)%000   9.<<<-e444   9.:::,88::E=''5'11779999.???,88::E=''u'555s   / >>A+ +A:9A:c           
      	   |r| j         nd}|r| j        nd}| j        t          j        k    r$t          j        ||| j        | j                  }n| j        t          j	        k    r&t          j
        ||dd| j        | j                  }n| j        t          j        k    rOddt          d	          fdt          d
          ff}t          j        ||t          j        |                    }nD| j        t          j        k    r%t          j        ||t#                                }n
| j        t          j        k    r%t          j        ||t)                                }n| j        t          j        t          j        fv r| j        j        }| j         | j        v r| j         nd}	|r|	t3          |          }|r|	r|	}|r4| j        t          j        k    rt4          }
nt6          }
 |
|||          }n?| j        t          j        k    rt8          }
t:          }nt<          }
t>          } |
||| |d| j        j          d                    }n| j        t          j!        k    rtE          ||          }n| j        t          j#        k    r)tI          ||rtK          j&        |          nd          }n~| j        t          j'        k    r\| j(        )                                }|rtT          ntV          }
|j,        -                                ||d}|s
| j.        |d<    |
di |}n| j        t          j/        k    r[| j(        )                                }|rt`          ntb          }
|j,        -                                ||d}|s
| j.        |d<    |
di |}n| j        t          j2        k    rt
          j3        nd}t          j4        |||          }| j5        r\tm          | j5        to          t          d          8                    ts          | j5                                                g|_:        | |_;        ty          |           |_=        | j>        rt          | j>                  |_@        |r| jA        t          jC        k    rd|_D        |S )a  
        Return a form field suitable for setting a CustomField's value for an object.

        set_initial: Set initial data for the field. This should be False when generating a field for bulk editing.
        enforce_required: Honor the value of CustomField.required. Set to False for filtering/bulk editing.
        enforce_visibility: Honor the value of CustomField.ui_visible. Set to False for filtering.
        for_csv_import: Return a form field suitable for bulk import of objects in CSV format.
        NF)r`   initial	min_value	max_value      )r`   r   
max_digitsdecimal_placesr   r   )Nz	---------TTrueFalserR   )r`   r   widget)rR   r`   r   z%/api/extras/custom-field-choice-sets/z	/choices/)api_url)rR   r`   r   r   )r`   r   )querysetr`   r   query_paramsz2Values must match this regex: <code>{regex}</code>rV   )rV   rW   r>   )Er@   r`   rN   r   r   r   IntegerFieldri   rj   r   DecimalFieldr   rt   NullBooleanFieldSelectr   	DateFieldr%   r   DateTimeFieldr&   r   r   rl   rR   r"   r   r   r   r#   r   r$   r   r   r!   	TYPE_JSONr    jsondumpsr   rd   r   r   r   r0   r   r   r   r   r   r   Textarea	CharFieldrk   r   r   r   r   r\   r7   r   r]   r^   r(   rM   rn   r   YESdisabled)r6   set_initialenforce_requiredenforce_visibilityfor_csv_importr   r`   fieldrR   default_choicefield_classwidget_classr7   r   r   s                  r9   to_form_fieldzCustomField.to_form_field  s    #.7$,,4$4?4==% 9.;;;&!11	  EE Y0===&! 11  EE Y0===#qyy!'

#G
 *!75<PW;X;X;X  EE
 Y0:::OXwz||\\\EE Y0>>>'7SaScScdddEE Y1=?U?fgggo-G-1\T\-I-IT\\tN 4~5*733  )~ )( 9 6 BBB"0KK"8K#GhPWXXX9 6 BBB"4K#,LL"<K#4L##%#'<0uX\XgXj0u0u0uvvv	   Y09997CCCEE Y0:::xPW9aG9L9L9L]abbbEE Y0<<<,88::E1?\--E\K!M--//$" F
 " D)-)C~&K))&))EE Y0AAA,88::E9Gl55MlK!M--//$" F
 " D)-)C~&K))&))EE (,y4J4X'X'XU^^^bFOXwvVVVE$ ""3 )!,`*a*a*h*h"()>"?"? +i + + ! !  $  $ii 	@-d.>??EO  	"$"26R6V"V"V!ENr:   Nc                 b   dd| j          i}|||d<   | j        t          j        t          j        t          j        fv r(t          j        }| j        t          j
        k    rd|d<   n:| j        t          j        k    rt          j        }n| j        t          j        k    rt          j        }n| j        t          j        k    rt           j        }n| j        t          j        k    rt          j        }n| j        t          j        k    rt          j        }n| j        t          j        k    rt          j        }nm| j        t          j        k    rt          j        }nK| j        t          j        k    rt          j        }n)| j        t          j        k    rt          j        }d|d<   ndS  |di |}| |_        |S )z
        Return a django_filters Filter instance suitable for this field type.

        :param lookup_expr: Custom lookup expression (optional)
        
field_namer   Nlookup_expr	icontainscontainsr>   )r?   rN   r   r   r   r   r   MultiValueCharFilterrg   CustomFieldFilterLogicChoicesFILTER_LOOSEr   MultiValueNumberFilterr   MultiValueDecimalFilterr   django_filtersBooleanFilterr   MultiValueDateFilterr   MultiValueDateTimeFilterr   r   MultiValueArrayFilterr   r   custom_field)r6   r
  r   filter_classfilter_instances        r9   	to_filterzCustomField.to_filterA  s    ;	;;
 "$/F=! 9&0&4&/
 
 

 #7L $A$NNN(3}% Y0==="9LL Y0===":LL Y0===)7LL Y0:::"7LL Y0>>>";LL Y0<<<"7LL Y0AAA"8LL Y0<<<"9LL Y0AAA"9L$.F=!! 4&,0000'+$r:   c                 L   |dvr{| j         t          j        t          j        fv rt          |          t          urt          t          d                    | j        rOt          j	        | j        |          s7t          t          d          
                    | j                            dS dS | j         t          j        k    rt          |          t          urt          t          d                    | j        @|| j        k     r5t          t          d          
                    | j                            | j        @|| j        k    r7t          t          d	          
                    | j        
                    dS dS | j         t          j        k    r	 t!          j        |           n/# t           j        $ r t          t          d                    w xY w| j        @|| j        k     r5t          t          d          
                    | j                            | j        @|| j        k    r7t          t          d	          
                    | j        
                    dS dS | j         t          j        k    r |dvrt          t          d                    | j         t          j        k    rYt          |          t*          urA	 t+          j        |           dS # t.          $ r t          t          d                    w xY wdS | j         t          j        k    rTt          |          t2          ur<	 t5          |           dS # t.          $ r t          t          d                    w xY wdS | j         t          j        k    rF|| j        j        vr6t          t          d          
                    || j                            dS | j         t          j        k    rdt?          |                               | j        j                  s6t          t          d          
                    || j                            dS | j         t          j!        k    rZt          |          t          urBt          t          d          
                    t          |          j"                            dS | j         t          j#        k    rt          |          tH          urBt          t          d          
                    t          |          j"                            |D ]J}t          |          t          ur0t          t          d          
                    |                    IdS dS | j%        rt          t          d                    dS )zR
        Validate a value according to the field's type validation rules.
        )N zValue must be a string.z Value must match regex '{regex}'r   zValue must be an integer.Nz Value must be at least {minimum})minimumzValue must not exceed {maximum})maximumzValue must be a decimal.)TF   r   zValue must be true or false.z4Date values must be in ISO 8601 format (YYYY-MM-DD).zFDate and time values must be in ISO 8601 format (YYYY-MM-DD HH:MM:SS).z4Invalid choice ({value}) for choice set {choiceset}.)r   	choicesetz7Invalid choice(s) ({value}) for choice set {choiceset}.z&Value must be an object ID, not {type}r   z.Value must be a list of object IDs, not {type}zFound invalid object ID: {id})idzRequired field cannot be empty.)&rN   r   r   r   r   r	   rt   rk   rematchr   r   intri   rj   r   decimalDecimalInvalidOperationr   r   r   r   r   r   r   r   r   rl   valuesr   setissubsetr   rF   r   listr`   )r6   r   r!  s      r9   r   zCustomField.validate  s    
"" y3=?U?cddd;;c)))!,E*F*FGGG( u$:OQV1W1W u)!,N*O*O*V*V]a]r*V*s*stttu u u u 4AAA;;c)))!,G*H*HIII*654CZ;Z;Z)<==DDTMdDee   *654CZ;Z;Z);<<CCDLcCdd   76;Z;Z 4AAAIOE****/ I I I)!,F*G*GHHHI*654CZ;Z;Z)<==DDTMdDee   *654CZ;Z;Z);<<CCDLcCdd   76;Z;Z 4AAAeSfFfFf%a(F&G&GHHH 4>>>;;d**i*511111% i i i-a0f.g.ghhhi +* 4BBB;;h../66666%   -fgg   /. 4@@@ 666)PQQXX"'&*o Y     76 4EEE5zz**4?+ABB )STT[["'&*o \      4@@@;;c)))!,T*U*U*\*\bfglbmbmbv*\*w*wxxx *) 4EEE;;d**)JKKRRX\]bXcXcXlRmm     ` `BBxxs**-a0O.P.P.W.W[].W.^.^___ + FE
` ` ] 	H!!$E"F"FGGG	H 	Hs$    F5 5,G!K- -'LM 'M=)TTTFr   )HrF   rG   rH   r
   ManyToManyFieldrt   r/   r   r   r   rN   
ForeignKeyPROTECTrd   r   r"  
IGNORECASEr?   r]   re   r^   BooleanFieldr`   r[   PositiveSmallIntegerFieldrf   r  r  rg   r    r@   r   rh   BigIntegerFieldri   rj   r)   rk   rl   r   ALWAYSrm   r   r   rn   ro   	TextFieldrc   r,   r0   clone_fieldsrv   r|   r   propertyr   r   r   rR   r   r   r   r   r   r   r   r   r   r  r  r   __classcell__r   s   @r9   r*   r*   G   sE       )6)$!@AA  L
 6QvYY&&0!>??  D ,&+.!VWW   6QvYY!)**N%UVVm  
 NWXXm"	  
  D& FQwZZ!g
 
	  E "!Q|__!TUU	  J #&"Q}%%  K
 #v"Qz]]!eff  H
 !V Q'((!TUU  F
 5F4Q''!
 
  M $6#Q~&&--:!cdd  L fQy\\!v
 
	  G -F,!C
 
   .V-Q'((!HII  F
 0/Q''!@AA	   0/Q''!@AA	   (v'"#Q)**!e
 
	 	 	 #"!."Q|__  J "!++2Q|__!OPP  J #&",,0Q}%%!VWW  K '6&Q~&&!?@@  L
  vQz]]  H
 ! ""GL1 1 1 1 1 1 1 1
F F F= = = G G XG/ / / / / + + X+   X
G G GI I I2 2 2

X 
X 
X
\ 
\ 
\
X 
X 
XL L L L L\     0N N N N`B B B BHcH cH cH cH cH cH cHr:   r*   c                       e Zd ZdZ ej        dd          Z ej        dd          Z ej        ded e	d          	          Z
 e e ej        d
          d          dd          Z ej        d e	d                    ZdZ G d d          Zd Z fdZd Zed             Zed             Zed             Zd Z fdZ xZS )r+   zZ
    Represents a set of choices available for choice and multi-choice custom fields.
    ra   T)rQ   r[   r_   )rQ   rT   rO   z)Base set of predefined choices (optional))rQ   rR   rT   rM   )rQ      )
base_fieldsize)rT   rU   Fz0Choices are automatically ordered alphabetically)r@   rM   )extra_choicesorder_alphabeticallyc                   >    e Zd ZdZ ed          Z ed          ZdS )CustomFieldChoiceSet.Metar?   zcustom field choice setzcustom field choice setsNrr   r>   r:   r9   rv   r@    s6        q233a :;;r:   rv   c                     | j         S r   rA  r{   s    r9   r|   zCustomFieldChoiceSet.__str__  s
    yr:   c                 x     t                      j        |i | | j                            d          | _        d S )Nr=  )r   r   r   r   _original_extra_choicesr   s      r9   r   zCustomFieldChoiceSet.__init__  s?    $)&))) (,}'8'8'I'I$$$r:   c                 0    t          d| j        g          S )Nzextras:customfieldchoicesetr~   r   r{   s    r9   r   z%CustomFieldChoiceSet.get_absolute_url  s    4DG9EEEEr:   c                 @   t          | d          seg | _        | j        r1| j                            t	          j        | j                             | j        r| j                            | j                   | j        rt          | j        d           | _        | j        S )zH
        Returns a concatenation of the base and extra choices.
        _choicesc                     | d         S Nr   r>   xs    r9   <lambda>z.CustomFieldChoiceSet.choices.<locals>.<lambda>)  s
    ! r:   key)	r   rG  base_choicesextendr   r   r=  r>  sortedr{   s    r9   rR   zCustomFieldChoiceSet.choices  s    
 tZ(( 	9DM  I$$[_T5F%G%GHHH! 9$$T%7888$ 	F"4=nnEEEDM}r:   c                 *    t          | j                  S r   )lenrR   r{   s    r9   choices_countz"CustomFieldChoiceSet.choices_count,  s    4<   r:   c                 $    d | j         D             S )zA
        Returns an iterator of the valid choice values.
        c              3   &   K   | ]}|d          V  dS )r   Nr>   )rA   rK  s     r9   	<genexpr>z.CustomFieldChoiceSet.values.<locals>.<genexpr>5  s&      ++!++++++r:   r   r{   s    r9   r(  zCustomFieldChoiceSet.values0  s    
 ,+dl++++r:   c           
         | j         s#| j        st          t          d                    | j        rt          d | j        D                       nt                      }| j        rt          d | j        D                       nt                      }||z
  x}r| j                                        D ]}|j                                        D ]}|	                                }|D ]}|j
        t          j        k    rd|j         d|i}nd|j         |i}|j                            t!          j        di |                                          r1t          t          d                              ||                    d S d S )	Nz"Must define base or extra choices.c                     g | ]
}|d          S r   r>   rA   cs     r9   r   z.CustomFieldChoiceSet.clean.<locals>.<listcomp>=  s)      
  
  
AaD 
  
  
r:   c                     g | ]
}|d          S rZ  r>   r[  s     r9   r   z.CustomFieldChoiceSet.clean.<locals>.<listcomp>@  s)     
 
 
AaD
 
 
r:   r   
__containszNCannot remove choice {choice} as there are {model} objects which reference it.)choicer7   r>   )rO  r=  r	   rt   rD  r)  rb   r   r/   r   rN   r   r   r?   r0   r5   r
   Qexistsr   )	r6   original_choicescurrent_choicesremoved_choicesr  object_typer7   r_  
query_argss	            r9   r   zCustomFieldChoiceSet.clean7  s     	K); 	K!!$H"I"IJJJ *63  
  
6 
  
  
   03 	
  ,# 
 
,
 
 
   &)ee 	 /@@? 	 $ 0 4 4 6 6  #/#<#@#@#B#B  K'3355E"1  ',0F0WWW*]@Q*]*]*]_e)fJJ*S@Q*S*SU[)\J =//0F0F:0F0FGGNNPP "1 !$t!" !""(&k&"J"J# # 	 	 r:   c                 |    | j         rt          | j        d           | _         t                      j        |i |S )Nc                     | d         S rI  r>   rJ  s    r9   rL  z+CustomFieldChoiceSet.save.<locals>.<lambda>Y  s
    !A$ r:   rM  )r>  rQ  r=  r   saver   s      r9   ri  zCustomFieldChoiceSet.saveU  sF     $ 	P!'(:!O!O!ODuww|T,V,,,r:   )rF   rG   rH   __doc__r
   r   r?   r^   CustomFieldChoiceSetBaseChoicesrt   rO  r   r=  r0  r>  r5  rv   r|   r   r   r6  rR   rT  r(  r   ri  r7  r8  s   @r9   r+   r+     s         6  D #&"  K $6#/!?@@	  L J
'v'3777	
 	
 	
   M /6.!FGG  
 =L< < < < < < < <
  J J J J JF F F   X ! ! X! , , X,  <- - - - - - - - -r:   r+   )Sr%  r   r"  r   r   r  djangor   django.confr   django.contrib.postgres.fieldsr   django.core.validatorsr   r	   	django.dbr
   django.urlsr   django.utils.htmlr   django.utils.safestringr   django.utils.translationr   rt   core.modelsr   extras.choicesextras.datar   netbox.modelsr   netbox.models.featuresr   r   netbox.searchr   	utilitiesr   utilities.datetimer   utilities.forms.fieldsr   r   r   r   r   r   r   r   r    r!   utilities.forms.utilsr"   utilities.forms.widgetsr#   r$   r%   r&   utilities.querysetsr'   'utilities.templatetags.builtins.filtersr(   utilities.validatorsr)   __all__r   r   STRINGr   r   INTEGERr   FLOATr   r   r   Managerfrom_querysetr,   r*   r+   r>   r:   r9   <module>r     st     				 # # # # # # # #                       5 5 5 5 5 5 B B B B B B B B             $ $ $ $ $ $ - - - - - - 6 6 6 6 6 6 " " " " " "     # # # # # # + + + + + + E E E E E E E E $ $ $ $ $ $       6 6 6 6 6 6                        3 2 2 2 2 2 \ \ \ \ \ \ \ \ \ \ \ \ 2 2 2 2 2 2 C C C C C C / / / / / / $j&7(**;');')9$j&7#Z%6
 
 
 
 
556HII 
 
 
(a
H a
H a
H a
H a
H, 46G a
H a
H a
HHp- p- p- p- p-<)=?P p- p- p- p- p-r:   