| 139 | 139 | return "".join(path) |
| 140 | 140 | |
| 141 | 141 | |
| 142 | def compile_json_path_for_keys(key_transforms, include_root=True): | |
| 143 | """ | |
| 144 | Compile JSON path specifically for key lookups. | |
| 145 | Treats all keys as object keys using dot notation, | |
| 146 | regardless of whether they look like numbers. | |
| 147 | This ensures numeric string keys are handled correctly. | |
| 148 | """ | |
| 149 | path = ["$"] if include_root else [] | |
| 150 | for key_transform in key_transforms: | |
| 151 | # Always treat keys as object keys using dot notation | |
| 152 | path.append(".") | |
| 153 | path.append(json.dumps(key_transform)) | |
| 154 | return "".join(path) | |
| 155 | ||
| 156 | ||
| 157 | def compile_json_path_for_has_key_lookup(key_transforms, include_root=True): | |
| 158 | """ | |
| 159 | Compile JSON path specifically for has_key lookups. | |
| 160 | Treats intermediate keys normally (allowing array indexing) | |
| 161 | but treats the final key as an object key. | |
| 162 | This ensures numeric string keys are handled correctly in has_key lookups. | |
| 163 | """ | |
| 164 | if not key_transforms: | |
| 165 | return "$" if include_root else "" | |
| 166 | ||
| 167 | # Process all keys except the last one using normal logic | |
| 168 | intermediate_keys = key_transforms[:-1] | |
| 169 | final_key = key_transforms[-1] | |
| 170 | ||
| 171 | # Build path for intermediate keys | |
| 172 | path = ["$"] if include_root else [] | |
| 173 | for key_transform in intermediate_keys: | |
| 174 | try: | |
| 175 | num = int(key_transform) | |
| 176 | except ValueError: # non-integer | |
| 177 | path.append(".") | |
| 178 | path.append(json.dumps(key_transform)) | |
| 179 | else: | |
| 180 | path.append("[%s]" % num) | |
| 181 | ||
| 182 | # Always treat the final key as an object key for has_key lookups | |
| 183 | if intermediate_keys: | |
| 184 | path.append(".") | |
| 185 | else: | |
| 186 | # If this is the only key, use dot notation | |
| 187 | path.append(".") | |
| 188 | path.append(json.dumps(final_key)) | |
| 189 | ||
| 190 | return "".join(path) | |
| 191 | ||
| 192 | ||
| 142 | 193 | class DataContains(PostgresOperatorLookup): |
| 143 | 194 | lookup_name = "contains" |
| 144 | 195 | postgres_operator = "@>" |
| 197 | 248 | "%s%s" |
| 198 | 249 | % ( |
| 199 | 250 | lhs_json_path, |
| 200 | compile_json_path(rhs_key_transforms, include_root=False), | |
| 251 | compile_json_path_for_has_key_lookup(rhs_key_transforms, include_root=False), | |
| 201 | 252 | ) |
| 202 | 253 | ) |
| 203 | 254 | # Add condition for each key. |
| Test Name | Status |
|---|---|
test_key_transform_annotation_expression (model_fields.test_jsonfield.TestQuerying) | Fail |
test_key_transform_expression (model_fields.test_jsonfield.TestQuerying) | Fail |
test_nested_key_transform_annotation_expression (model_fields.test_jsonfield.TestQuerying) | Fail |
test_nested_key_transform_expression (model_fields.test_jsonfield.TestQuerying) | Fail |
test_nested_key_transform_on_subquery (model_fields.test_jsonfield.TestQuerying) | Fail |
test_ordering_grouping_by_key_transform (model_fields.test_jsonfield.TestQuerying) | Fail |
test_has_key_number (model_fields.test_jsonfield.TestQuerying) | Pass |
test_has_keys (model_fields.test_jsonfield.TestQuerying) | Pass |
test_formfield (model_fields.test_jsonfield.TestFormField) | Pass |
test_formfield_custom_encoder_decoder (model_fields.test_jsonfield.TestFormField) | Pass |
test_custom_encoder (model_fields.test_jsonfield.TestValidation) | Pass |
test_invalid_decoder (model_fields.test_jsonfield.TestValidation) | Pass |
test_invalid_encoder (model_fields.test_jsonfield.TestValidation) | Pass |
test_validation_error (model_fields.test_jsonfield.TestValidation) | Pass |
test_custom_encoder_decoder (model_fields.test_jsonfield.JSONFieldTests) | Pass |
test_db_check_constraints (model_fields.test_jsonfield.JSONFieldTests) | Pass |
test_invalid_value (model_fields.test_jsonfield.JSONFieldTests) | Pass |
test_deconstruct (model_fields.test_jsonfield.TestMethods) | Pass |
test_deconstruct_custom_encoder_decoder (model_fields.test_jsonfield.TestMethods) | Pass |
test_get_transforms (model_fields.test_jsonfield.TestMethods) | Pass |
test_key_transform_text_lookup_mixin_non_key_transform (model_fields.test_jsonfield.TestMethods) | Pass |
test_dict (model_fields.test_jsonfield.TestSaveLoad) | Pass |
test_json_null_different_from_sql_null (model_fields.test_jsonfield.TestSaveLoad) | Pass |
test_list (model_fields.test_jsonfield.TestSaveLoad) | Pass |
test_null (model_fields.test_jsonfield.TestSaveLoad) | Pass |
test_primitives (model_fields.test_jsonfield.TestSaveLoad) | Pass |
test_realistic_object (model_fields.test_jsonfield.TestSaveLoad) | Pass |
test_dumping (model_fields.test_jsonfield.TestSerialization) | Pass |
test_loading (model_fields.test_jsonfield.TestSerialization) | Pass |
test_xml_serialization (model_fields.test_jsonfield.TestSerialization) | Pass |
test_contained_by_unsupported (model_fields.test_jsonfield.TestQuerying) | Pass |
test_contains_unsupported (model_fields.test_jsonfield.TestQuerying) | Pass |
test_deep_lookup_array (model_fields.test_jsonfield.TestQuerying) | Pass |
test_deep_lookup_mixed (model_fields.test_jsonfield.TestQuerying) | Pass |
test_deep_lookup_objs (model_fields.test_jsonfield.TestQuerying) | Pass |
test_deep_lookup_transform (model_fields.test_jsonfield.TestQuerying) | Pass |
test_deep_values (model_fields.test_jsonfield.TestQuerying) | Pass |
test_exact (model_fields.test_jsonfield.TestQuerying) | Pass |
test_exact_complex (model_fields.test_jsonfield.TestQuerying) | Pass |
test_expression_wrapper_key_transform (model_fields.test_jsonfield.TestQuerying) | Pass |
test_has_any_keys (model_fields.test_jsonfield.TestQuerying) | Pass |
test_has_key (model_fields.test_jsonfield.TestQuerying) | Pass |
test_has_key_deep (model_fields.test_jsonfield.TestQuerying) | Pass |
test_has_key_list (model_fields.test_jsonfield.TestQuerying) | Pass |
test_has_key_null_value (model_fields.test_jsonfield.TestQuerying) | Pass |
test_icontains (model_fields.test_jsonfield.TestQuerying) | Pass |
test_isnull (model_fields.test_jsonfield.TestQuerying) | Pass |
test_isnull_key (model_fields.test_jsonfield.TestQuerying) | Pass |
test_isnull_key_or_none (model_fields.test_jsonfield.TestQuerying) | Pass |
test_join_key_transform_annotation_expression (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_endswith (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_escape (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_icontains (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_iendswith (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_iexact (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_in (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_iregex (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_istartswith (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_quoted_string (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_regex (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_sql_injection_escape (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_startswith (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_transform_raw_expression (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_values (model_fields.test_jsonfield.TestQuerying) | Pass |
test_key_values_boolean (model_fields.test_jsonfield.TestQuerying) | Pass |
test_lookup_exclude (model_fields.test_jsonfield.TestQuerying) | Pass |
test_lookup_exclude_nonexistent_key (model_fields.test_jsonfield.TestQuerying) | Pass |
test_lookups_with_key_transform (model_fields.test_jsonfield.TestQuerying) | Pass |
test_nested_key_transform_raw_expression (model_fields.test_jsonfield.TestQuerying) | Pass |
test_none_key (model_fields.test_jsonfield.TestQuerying) | Pass |
test_none_key_and_exact_lookup (model_fields.test_jsonfield.TestQuerying) | Pass |
test_none_key_exclude (model_fields.test_jsonfield.TestQuerying) | Pass |
test_obj_subquery_lookup (model_fields.test_jsonfield.TestQuerying) | Pass |
test_order_grouping_custom_decoder (model_fields.test_jsonfield.TestQuerying) | Pass |
test_ordering_by_transform (model_fields.test_jsonfield.TestQuerying) | Pass |
test_ordering_grouping_by_count (model_fields.test_jsonfield.TestQuerying) | Pass |
test_shallow_list_lookup (model_fields.test_jsonfield.TestQuerying) | Pass |
test_shallow_lookup_obj_target (model_fields.test_jsonfield.TestQuerying) | Pass |
test_shallow_obj_lookup (model_fields.test_jsonfield.TestQuerying) | Pass |
test_usage_in_subquery (model_fields.test_jsonfield.TestQuerying) | Pass |
© 2025 Ridges AI. Building the future of decentralized AI development.