o 3aL@shddlZddlmZddlmZmZddlmZmZm Z ddl m Z ddl m Z mZddlmZdd lmZdd lmZd gZGd d d eeZdHddZGddde ZGddde ZGddde ZGdddeZGdddeZGdddeZGddde jZ e!ee!ee!ee!ee!ee!e GdddeZ"Gd d!d!e"Z#Gd"d#d#Z$Gd$d%d%Z%Gd&d'd'e j&Z'Gd(d)d)e j(Z)Gd*d+d+e Z*Gd,d-d-e%e$e j+Z,Gd.d/d/e%e$e j-Z.Gd0d1d1e$e j/Z0Gd2d3d3e%e$e j1Z2Gd4d5d5e$e j3Z4Gd6d7d7e%e$e j5Z6Gd8d9d9e$e j7Z8Gd:d;d;e%e$e j9Z:Gdd?d?e;e j<Z=Gd@dAdAe;e j>Z?GdBdCdCe;e j@ZAGdDdEdEe;e jBZCe"!e)e"!e*e"!e,e"!e'e"!e.e"!e0e"!e2e"!e4e"!e6e"!e8e"!e:e"!e=e"!e?e"!eAe"!eCGdFdGdGZDdS)IN)forms)checks exceptions)NotSupportedError connectionsrouter)lookups)PostgresOperatorLookup Transform) gettext_lazy)Field)CheckFieldDefaultMixin JSONFieldcseZdZdZedZdediZdZ dfdd Zfd d Z d d Z fd dZ ddZ ddZ ddZfddZfddZddZfddZZS)rFz A JSON objectinvalidzValue must be valid JSON.)dictz{}Nc sN|r t|s td|rt|std||_||_tj||fi|dS)Nz0The encoder parameter must be a callable object.z0The decoder parameter must be a callable object.)callable ValueErrorencoderdecodersuper__init__)self verbose_namenamerrkwargs __class__>/usr/lib/python3/dist-packages/django/db/models/fields/json.pyrs  zJSONField.__init__c s4tjdi|}|dpg}||||S)N databasesr)rcheckgetextend_check_supported)rrerrorsr rrrr!$szJSONField.checkcCszg}|D]6}t||jsqt|}|jjjr |jjj|jkr qd|jjjvs:|jj s:| t j d|j |jddq|S)Nsupports_json_fieldz%s does not support JSONFields.z fields.E180)objid)rallow_migrate_modelmodelr_metarequired_db_vendorvendorrequired_db_featuresfeaturesr&appendrError display_name)rr r%db connectionrrrr$*s.zJSONField._check_supportedcsFt\}}}}|jdur|j|d<|jdur|j|d<||||fS)Nrr)r deconstructrr)rrpathargsrrrrr5Cs      zJSONField.deconstructcCsP|dur|St|trt|ts|Sz tj||jdWStjy'|YSwNcls) isinstance KeyTransformstrjsonloadsrJSONDecodeError)rvalue expressionr4rrr from_db_valueKszJSONField.from_db_valuecCsdS)Nrrrrrrget_internal_typeWszJSONField.get_internal_typecCs|dur|Stj||jdSr8)r>dumpsr)rrArrrget_prep_valueZszJSONField.get_prep_valuecst|}|r |St|SN)r get_transformKeyTransformFactory)rr transformrrrrI_s zJSONField.get_transformcsNt||z tj||jdWdSty&tj|jddd|idw)Nr9rrA)codeparams) rvalidater>rFr TypeErrorrValidationErrorerror_messages)rrAmodel_instancerrrrNes zJSONField.validatecCs ||SrH)value_from_object)rr'rrrvalue_to_stringp zJSONField.value_to_stringc s$tjditj|j|jd|S)N) form_classrrr)r formfieldrrrr)rrrrrrWss zJSONField.formfield)NNNN)__name__ __module__ __qualname__empty_strings_allowed_ descriptiondefault_error_messages _default_hintrr!r$r5rCrErGrIrNrTrW __classcell__rrrrrs$      Tc Csj|rdgng}|D]&}zt|}Wnty'|d|t|Yq w|d|q d|S)N$.z[%s])intrr0r>rFjoin)key_transforms include_rootr6 key_transformnumrrrcompile_json_path|s    rjc@eZdZdZdZddZdS) DataContainscontainsz@>cCsP|jjstd|||\}}|||\}}t|t|}d||f|fS)Nz:contains lookup is not supported on this database backend.JSON_CONTAINS(%s, %s)r/supports_json_field_containsr process_lhs process_rhstuplercompilerr4lhs lhs_paramsrhs rhs_paramsrMrrras_sqlzDataContains.as_sqlNrXrYrZ lookup_namepostgres_operatorrzrrrrrl rlc@rk) ContainedBy contained_byz<@cCsP|jjstd|||\}}|||\}}t|t|}d||f|fS)Nz>contained_by lookup is not supported on this database backend.rnrortrrrrzr{zContainedBy.as_sqlNr|rrrrrrrcsBeZdZdZd ddZddZddZfdd Zd d ZZ S) HasKeyLookupNc Cst|jtr|j||\}}}t|}n |||\}}d}||}|j} g} t| ttfs2| g} | D]!} t| trE| ||^} } n| g} | d|t| ddfq4|j rfd|j |gt | }|t|t| fS)Nraz%s%sF)rgz(%s)) r;rvr<preprocess_lhsrjrqrxlistrsr0logical_operatorrelen)rrur4templatervrwlhs_key_transforms lhs_json_pathsqlrxrykeyr\rhs_key_transformsrrrrzs*     zHasKeyLookup.as_sqlcC|j||ddS)Nz"JSON_CONTAINS_PATH(%s, 'one', %%s)rrzrrur4rrras_mysqlzHasKeyLookup.as_mysqlcCs$|j||dd\}}|t|gfS)NzJSON_EXISTS(%s, '%%s')r)rzrs)rrur4rrMrrr as_oracleszHasKeyLookup.as_oraclecsXt|jtr%|j||^}}|ddD] }t||j|_q|d|_t||S)N)r;rxr<rrvr as_postgresql)rrur4r\rrrrrrs  zHasKeyLookup.as_postgresqlcCr)NJSON_TYPE(%s, %%s) IS NOT NULLrrrrrr as_sqliterzHasKeyLookup.as_sqliterH) rXrYrZrrzrrrrr`rrrrrs  rc@eZdZdZdZdZdS)HasKeyhas_key?FN)rXrYrZr}r~ prepare_rhsrrrrrrc@s eZdZdZdZdZddZdS)HasKeyshas_keysz?&z AND cCsdd|jDS)NcSsg|]}t|qSr)r=).0itemrrr sz+HasKeys.get_prep_lookup..)rxrDrrrget_prep_lookuprzHasKeys.get_prep_lookupN)rXrYrZr}r~rrrrrrrs  rc@r) HasAnyKeys has_any_keysz?|z OR N)rXrYrZr}r~rrrrrrrrc,eZdZdZfddZfddZZS) JSONExactTcsPt||\}}|jdkr$t||\}}|dkr$|dgkr$d|}||fS)Nsqlite%szJSON_TYPE(%s, '$'))rrqr-rr)rrur4rvrwrxryrrrrqs  zJSONExact.process_lhscsVt||\}}|dkr|dgkrdg}|jdkr'dgt|}|t|}||fS)NrnullmysqlJSON_EXTRACT(%s, '$'))rrrr-rrs)rrur4rxryfuncrrrrrs  zJSONExact.process_rhs)rXrYrZcan_use_none_as_rhsrqrrr`rrrrrs  rcsLeZdZdZdZfddZddZddZd d Zd d Z d dZ Z S)r<z->z#>cs tj|i|t||_dSrH)rrr=key_name)rrr7rrrrrszKeyTransform.__init__cCsf|jg}|j}t|tr|d|j|j}t|ts ||\}}|jdkr.dd|D}|||fS)NroraclecSsg|]}|ddqS)%z%%)replace)rrrrrr sz/KeyTransform.preprocess_lhs..)rrvr;r<insertcompiler-)rrur4rfpreviousrvrMrrrrs    zKeyTransform.preprocess_lhscC0|||\}}}t|}d|t||ffSNzJSON_EXTRACT(%s, %%s)rrjrsrrur4rvrMrf json_pathrrrr#zKeyTransform.as_mysqlcCs6|||\}}}t|}d||fdt|dfS)Nz4COALESCE(JSON_QUERY(%s, '%s'), JSON_VALUE(%s, '%s'))rrrrrr(s  zKeyTransform.as_oraclecCs|||\}}}t|dkrd||jf}|t||ffSzt|j}Wn ty2|j}Ynwd||jft||ffS)Nr z (%s %s %%s))rrpostgres_nested_operatorrsrdrrr~)rrur4rvrMrfrlookuprrrr0s   zKeyTransform.as_postgresqlcCrrrrrrrr;rzKeyTransform.as_sqlite) rXrYrZr~rrrrrrrr`rrrrr<s   r<c@seZdZdZdZdS)KeyTextTransformz->>z#>>N)rXrYrZr~rrrrrrAsrcs eZdZdZfddZZS)KeyTransformTextLookupMixinz Mixin for combining with a lookup expecting a text lhs from a JSONField key lookup. On PostgreSQL, make use of the ->> operator instead of casting key values to text and performing the lookup on the resulting representation. csLt|ts tdt|jg|jRi|j}tj|g|Ri|dS)NzLTransform should be an instance of KeyTransform in order to use this lookup.) r;r<rOrrsource_expressionsextrarr)rrhr7rkey_text_transformrrrrMs z$KeyTransformTextLookupMixin.__init__)rXrYrZ__doc__rr`rrrrrFsrcr)CaseInsensitiveMixinz Mixin to allow case-insensitive comparison of JSON values on MySQL. MySQL handles strings used in JSON context using the utf8mb4_bin collation. Because utf8mb4_bin is a binary collation, comparison of JSON values is case-sensitive. c0t||\}}|jdkrd||fS||fSNrz LOWER(%s))rrqr-)rrur4rvrwrrrrqa  z CaseInsensitiveMixin.process_lhscrr)rrrr-rrur4rxryrrrrrgrz CaseInsensitiveMixin.process_rhs)rXrYrZrrqrrr`rrrrrZs rc@eZdZddZddZdS)KeyTransformIsNullcCs\t|jj|jj||\}}|js||fS|j||\}}}d||ft|t|fS)Nz(NOT %s OR %s IS NULL))rrvrrrxrrs)rrur4rrMrvrwr\rrrrpszKeyTransformIsNull.as_oraclecCs,d}|jsd}t|jj|jjj|||dS)NzJSON_TYPE(%s, %%s) IS NULLrr)rxrrvrrz)rrur4rrrrr{szKeyTransformIsNull.as_sqliteN)rXrYrZrrrrrrrns rceZdZfddZZS)KeyTransformIncst||||\}}t|ds8|jjs8|jdkr1t|}d}t|t t fr,|d}n |d}n|jdvr8d}|jdkrD|j rDd |}||fS) Nrzr9%s(JSON_OBJECT('value' VALUE %%s FORMAT JSON), '$.value') JSON_QUERY JSON_VALUE>rrrrzJSON_UNQUOTE(%s)) rresolve_expression_parameterhasattrr/has_native_json_fieldr-r>r?r;rrmysql_is_mariadb)rrur4rparamrMrArrrrs$     z+KeyTransformIn.resolve_expression_parameter)rXrYrZrr`rrrrrrcs4eZdZfddZfddZfddZZS)KeyTransformExactcsbt||\}}|jdkr-t||\}}|dkr-|dgkr-|j||^}}d|}||fS)NrrrzJSON_TYPE(%s, %%s))rrqr-rrrvr)rrur4rvrwrxryr\rrrrqs zKeyTransformExact.process_lhscst|jtrttj|||St||\}}|jdkrLg}d}|D]}t |}t|t t fr:| |dq$| |dq$|t |}||fS|jdkr^dd|D}|t |}||fS)NrrrrrcSsg|] }|dkr dndqS)rrrrrrArrrrsz1KeyTransformExact.process_rhs..)r;rxr<rrExactrrr-r>r?rrr0rs)rrur4rxryrrrArrrrrs"      zKeyTransformExact.process_rhsc st||\}}|dgkr?t|jj|jj}|||\}}|jd|jd}|||\} } d|| ft|t| fSt||S)NrisnullTz %s AND %s) rrrrrvrr get_lookuprzrs) rrur4rxry has_key_expr has_key_sqlhas_key_params is_null_expr is_null_sqlis_null_paramsrrrrs  zKeyTransformExact.as_oracle)rXrYrZrqrrrr`rrrrrs  rc@ eZdZdS)KeyTransformIExactNrXrYrZrrrrrrc@r)KeyTransformIContainsNrrrrrrrrc@r)KeyTransformStartsWithNrrrrrrrrc@r)KeyTransformIStartsWithNrrrrrrrrc@r)KeyTransformEndsWithNrrrrrrrrc@r)KeyTransformIEndsWithNrrrrrrrrc@r)KeyTransformRegexNrrrrrrrrc@r)KeyTransformIRegexNrrrrrrrrcr)KeyTransformNumericLookupMixincs0t||\}}|jjsdd|D}||fS)NcSsg|]}t|qSr)r>r?rrrrrsz>KeyTransformNumericLookupMixin.process_rhs..)rrrr/rrrrrrrsz*KeyTransformNumericLookupMixin.process_rhs)rXrYrZrrr`rrrrrrrc@r)KeyTransformLtNrrrrrrrrc@r)KeyTransformLteNrrrrrrrrc@r)KeyTransformGtNrrrrrrrrc@r)KeyTransformGteNrrrrrrrrc@r)rJcCs ||_dSrH)r)rrrrrrrUzKeyTransformFactory.__init__cOst|jg|Ri|SrH)r<r)rr7rrrr__call__szKeyTransformFactory.__call__N)rXrYrZrrrrrrrJs rJ)T)Er>djangor django.corerr django.dbrrrdjango.db.modelsrdjango.db.models.lookupsr r django.utils.translationr r\rcr mixinsr__all__rrjrlrrrrrrrregister_lookupr<rrrIsNullrInrrIExactr IContainsr StartsWithr IStartsWithrEndsWithr IEndsWithrRegexrIRegexrrLessThanrLessThanOrEqualr GreaterThanrGreaterThanOrEqualrrJrrrrsz      l 4       2,