try:
from bitfield.types import Bit, BitHandler
except:
Bit = None
BitHandler = None
# AND
[docs]def is_flag_set_for_status(status, flag):
# this is because checking for equality on bithandlers will return false
# when compared to an int of the same value
if BitHandler and type(status) == BitHandler:
status = int(status)
return (status & flag) == flag
[docs]def is_flag_field_set_for_status(status, flag_field):
if Bit and type(flag_field) == Bit:
return is_flag_set_for_status(status, flag_field.mask)
return is_flag_set_for_status(status, (1 << flag_field))
[docs]def unset_flag_field_for_status(status, flag_field):
if Bit and type(flag_field) == Bit:
return unset_flag_for_status(status, flag_field.mask)
return unset_flag_for_status(status, (1 << flag_field))
[docs]def unset_flag_for_status(status, flag):
return status & ~flag
# OR
[docs]def set_flag_for_status(status, flag):
return status | flag
[docs]def set_flag_field_for_status(status, flag_field):
if Bit and type(flag_field) == Bit:
# django-bitfield has the field already shifted
return set_flag_for_status(status, flag_field.mask)
return set_flag_for_status(status, (1 << flag_field))
[docs]def get_field_from_source(source):
return source.split('.')[-1]
[docs]def get_django_query_string_from_source(source):
return "__".join(source.split(".")[:-1])
[docs]def get_parent_model(instance, key_string):
keys = key_string.split('.')
for key in keys[:-1]:
if key in [f.name for f in instance._meta.many_to_many]:
return None
instance = getattr(instance, key)
return instance
[docs]def check_and_set_flag(parent_model, field, flag):
status_value = getattr(parent_model, field)
if not is_flag_field_set_for_status(status_value, flag):
status_value = set_flag_field_for_status(status_value, flag)
setattr(parent_model, field, status_value)
parent_model.save(update_fields=[field])