mirror of
https://github.com/netbox-community/netbox.git
synced 2025-09-06 14:23:36 -06:00
Introduce JSONEmpty lookup
This commit is contained in:
parent
f2b29273d0
commit
8ff2bc5dff
@ -1,4 +1,5 @@
|
|||||||
from django.db.models import CharField, Lookup
|
from django.db.models import CharField, JSONField, Lookup
|
||||||
|
from django.db.models.fields.json import KeyTextTransform
|
||||||
|
|
||||||
from .fields import CachedValueField
|
from .fields import CachedValueField
|
||||||
|
|
||||||
@ -18,6 +19,30 @@ class Empty(Lookup):
|
|||||||
return f"CAST(LENGTH({sql}) AS BOOLEAN) IS TRUE", params
|
return f"CAST(LENGTH({sql}) AS BOOLEAN) IS TRUE", params
|
||||||
|
|
||||||
|
|
||||||
|
class JSONEmpty(Lookup):
|
||||||
|
"""
|
||||||
|
Support "empty" lookups for JSONField keys.
|
||||||
|
|
||||||
|
A key is considered empty if it is "", null, or does not exist.
|
||||||
|
"""
|
||||||
|
lookup_name = "empty"
|
||||||
|
|
||||||
|
def as_sql(self, compiler, connection):
|
||||||
|
# self.lhs.lhs is the parent expression (could be a JSONField or another KeyTransform)
|
||||||
|
# Rebuild the expression using KeyTextTransform to guarantee ->> (text)
|
||||||
|
text_expr = KeyTextTransform(self.lhs.key_name, self.lhs.lhs)
|
||||||
|
lhs_sql, lhs_params = compiler.compile(text_expr)
|
||||||
|
|
||||||
|
value = self.rhs
|
||||||
|
if value not in (True, False):
|
||||||
|
raise ValueError("The 'empty' lookup only accepts True or False.")
|
||||||
|
|
||||||
|
condition = 'NOT ' if value else ''
|
||||||
|
sql = f"(NULLIF({lhs_sql}, '') IS {condition}NULL)"
|
||||||
|
|
||||||
|
return sql, lhs_params
|
||||||
|
|
||||||
|
|
||||||
class NetHost(Lookup):
|
class NetHost(Lookup):
|
||||||
"""
|
"""
|
||||||
Similar to ipam.lookups.NetHost, but casts the field to INET.
|
Similar to ipam.lookups.NetHost, but casts the field to INET.
|
||||||
@ -45,5 +70,6 @@ class NetContainsOrEquals(Lookup):
|
|||||||
|
|
||||||
|
|
||||||
CharField.register_lookup(Empty)
|
CharField.register_lookup(Empty)
|
||||||
|
JSONField.register_lookup(JSONEmpty)
|
||||||
CachedValueField.register_lookup(NetHost)
|
CachedValueField.register_lookup(NetHost)
|
||||||
CachedValueField.register_lookup(NetContainsOrEquals)
|
CachedValueField.register_lookup(NetContainsOrEquals)
|
||||||
|
@ -603,8 +603,12 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
|
|||||||
if lookup_expr is not None:
|
if lookup_expr is not None:
|
||||||
kwargs['lookup_expr'] = lookup_expr
|
kwargs['lookup_expr'] = lookup_expr
|
||||||
|
|
||||||
|
# 'Empty' lookup is always a boolean
|
||||||
|
if lookup_expr == 'empty':
|
||||||
|
filter_class = django_filters.BooleanFilter
|
||||||
|
|
||||||
# Text/URL
|
# Text/URL
|
||||||
if self.type in (
|
elif self.type in (
|
||||||
CustomFieldTypeChoices.TYPE_TEXT,
|
CustomFieldTypeChoices.TYPE_TEXT,
|
||||||
CustomFieldTypeChoices.TYPE_LONGTEXT,
|
CustomFieldTypeChoices.TYPE_LONGTEXT,
|
||||||
CustomFieldTypeChoices.TYPE_URL,
|
CustomFieldTypeChoices.TYPE_URL,
|
||||||
|
Loading…
Reference in New Issue
Block a user