Skip to content

Conversation

@pranshustuff
Copy link

@pranshustuff pranshustuff commented Oct 1, 2025

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Reference to Existing Issue

Fixes #334.

Description of Changes

  • Made verb field in notification nullable.
  • Added a property verb under AbstractNotification in models that uses configured value from NOTIFICATION_TYPES and uses DB value as a fallback if that fails.

Screenshot

simplescreenrecorder-2025-10-01_15.25.40.mp4

Pranshu and others added 2 commits October 1, 2025 16:23
Made verb field in notification nullable. Created
a property verb under AbstractNotification in models
that prioritizes verb from NOTIFICATION_TYPES and
uses DB as a fallback.

Fixes openwisp#334
@pranshustuff pranshustuff changed the title [fix] Dynamic updating of notification verb #334 [fix] Dynamically updating notification verb #334 Oct 1, 2025
@pranshustuff
Copy link
Author

I think the CI builds are failing because the ./manage.py makemigrations isn't being run in the workflow, the migration I added solved the issue of the NOT NULL constraint on verb when I tested locally.

Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @pranshustuff.

We need a test which replicates the bug described in #334. The test should fail without your patch and should pass with it.

Please also make sure the CI build passes.

See more comments below.

Added a test to verify correct behaviour and specified
exceptions in the try-except in the verb property in
models.py

Fixes openwisp#334
@pranshustuff
Copy link
Author

pranshustuff commented Oct 1, 2025

I've made the requested changes.

It should pass CI bulds now I think.

Fixes openwisp#334
Copy link
Member

@nemesifier nemesifier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@github-project-automation github-project-automation bot moved this from To do (general) to In progress in OpenWISP Contributor's Board Oct 1, 2025
Removed verb field from DB, verb now updates from
config from NOTIFICATION_TYPES.

Fixes openwisp#334
@pranshustuff
Copy link
Author

pranshustuff commented Oct 1, 2025

Ok locally, it passed the tests, on sample app too. I added a test that mimics the bug in test_notifications.py.

Not deleting DB field verb, so it is backwards
compatible. Changed instances of .verb to .resolved_verb.
Resolved_verb property allows .verb as fallback.

Fixes openwisp#334.
@pranshustuff
Copy link
Author

pranshustuff commented Oct 14, 2025

I made the requested changes.
The property is now called resolved_verb which gets verb from config and falls back to verb if config.get() fails. I changed many instances of .verb to .resolved_verb in the tests, so the tests mimic the logic too. And verb field is not being removed, it is being altered to nullable.

"email_subject": "[{site.name}] Default Notification Subject",
"message": (
"Default notification with {notification.verb} and level {notification.level}"
"Default notification with {notification.resolved_verb} and level {notification.level}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will break the existing integration with other OpenWISP apps.

We have a context manager notification_render_attributes , Can we set the verb using notification type in the context manage and then clear the field (set to None) in cleanup process?

@contextmanager
def notification_render_attributes(obj, **attrs):
"""
This context manager sets temporary attributes on
the notification object to allowing rendering of
notification.
It can only be used to set aliases of the existing attributes.
By default, it will set the following aliases:
- actor_link -> actor_url
- action_link -> action_url
- target_link -> target_url
"""
defaults = {
"actor_link": "actor_url",
"action_link": "action_url",
"target_link": "target_url",
}
defaults.update(attrs)
for target_attr, source_attr in defaults.items():
setattr(obj, target_attr, getattr(obj, source_attr))
# In Django 5.1+, GenericForeignKey fields defined in parent models can no longer
# be overridden in child models (https://code.djangoproject.com/ticket/36295).
# To avoid multiple database queries, we explicitly set these attributes here
# using our cached _related_object method instead of relying on the default
# GenericForeignKey accessor which would bypass our caching mechanism.
setattr(obj, "actor", obj._related_object("actor"))
setattr(obj, "action_object", obj._related_object("action_object"))
setattr(obj, "target", obj._related_object("target"))
yield obj
for attr in defaults.keys():
delattr(obj, attr)

It should behave similarly to the resolved_verb property.

db_verb = obj.verb
# we give preference to the verb stored in the database
verb = obj.verb or config.get('verb')

# In cleanup 
obj.verb = db_verb

Do you think a solution like this will solve our problem?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not tested it yet. But I think it's a plausible solution.

I am a little busy at the moment. I'll get back to you sometime around next week after investigating this approach.

Thanks again for the review!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

[bug] Notification verb is saved in database

3 participants