-
-
Notifications
You must be signed in to change notification settings - Fork 226
[fix] Detect device organization change #1091
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Added signal handler to update device config status when organizationconfig settings change and tests for the same. Fixes #1070
Added signal handler to update device config status when organization config settings change and tests for the same. Fixes #1070
Replaced direct model imports with swapper to avoid premature access to models during Django app initialization. Fixes #1070
Replaced direct model imports with swapper to avoid premature access to models during Django app initialization during tests. Fixes #1070
Added # noqa to prevent unused import error for now and ensure signal handlers are registered correctly, we can revisit this approach and discuss cleaner alternatives for this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This solution is not consistent with what we're using now, see:
openwisp-controller/openwisp_controller/config/base/device.py
Lines 123 to 128 in 4ea68be
def _set_initial_values_for_changed_checked_fields(self): | |
for field in self._changed_checked_fields: | |
if self._is_deferred(field): | |
setattr(self, f"_initial_{field}", models.DEFERRED) | |
else: | |
setattr(self, f"_initial_{field}", getattr(self, field)) |
openwisp-controller/openwisp_controller/config/base/device.py
Lines 310 to 387 in 4ea68be
def _get_initial_values_for_checked_fields(self): | |
# Refresh values from database only when the checked field | |
# was initially deferred, but is no longer deferred now. | |
# Store the present value of such fields because they will | |
# be overwritten fetching values from database | |
# NOTE: Initial value of a field will only remain deferred | |
# if the current value of the field is still deferred. This | |
present_values = dict() | |
for field in self._changed_checked_fields: | |
if getattr( | |
self, f"_initial_{field}" | |
) == models.DEFERRED and not self._is_deferred(field): | |
present_values[field] = getattr(self, field) | |
# Skip fetching values from database if all of the checked fields are | |
# still deferred, or were not deferred from the begining. | |
if not present_values: | |
return | |
self.refresh_from_db(fields=present_values.keys()) | |
for field in self._changed_checked_fields: | |
setattr(self, f"_initial_{field}", field) | |
setattr(self, field, present_values[field]) | |
def _check_name_changed(self): | |
if self._initial_name == models.DEFERRED: | |
return | |
if self._initial_name != self.name: | |
device_name_changed.send( | |
sender=self.__class__, | |
instance=self, | |
) | |
if self._has_config(): | |
self.config.set_status_modified() | |
def _check_group_id_changed(self): | |
if self._initial_group_id == models.DEFERRED: | |
return | |
if self._initial_group_id != self.group_id: | |
self._send_device_group_changed_signal( | |
self, self.group_id, self._initial_group_id | |
) | |
def _check_management_ip_changed(self): | |
if self._initial_management_ip == models.DEFERRED: | |
return | |
if self.management_ip != self._initial_management_ip: | |
management_ip_changed.send( | |
sender=self.__class__, | |
management_ip=self.management_ip, | |
old_management_ip=self._initial_management_ip, | |
instance=self, | |
) | |
self._initial_management_ip = self.management_ip | |
def _check_organization_id_changed(self): | |
""" | |
Returns "True" if the device's organization has changed. | |
""" | |
return ( | |
self._initial_organization_id != models.DEFERRED | |
and self.organization_id != self._initial_organization_id | |
) | |
@classmethod | |
def _send_device_group_changed_signal(cls, instance, group_id, old_group_id): | |
""" | |
Emits ``device_group_changed`` signal. | |
Called also by ``change_device_group`` admin action method. | |
""" | |
device_group_changed.send( | |
sender=cls, | |
instance=instance, | |
group_id=group_id, | |
old_group_id=old_group_id, | |
) |
It seems we already check organization_id
but we don't check organization
.
Please look at the existing code before writing new code.
Look for an existing test for the case in which organization_id
is changed, there should be already a test for that, we could extend it to also check for organization
.
Modified OrganizationConfigSettings.save() to mark related device configs as modified when the context (configuration variables) changes. This aligns with existing patterns without altering device internals. Fixes #1070
@nemesifier |
Although I do check the existing implementations for every issue, I'll make sure to be more thorough going forward and not push one shot fixes with new code. |
Checklist
Reference to Existing Issue
Closes #1070.
Description of Changes
Added a new file signal_handlers.py that listens for changes to organization settings and marks related device configurations as modified when those settings change.