Skip to content

[fix] Auto-fill organization from master subnet in SubnetDivisionRule#1275

Open
peterishakvr12 wants to merge 3 commits intoopenwisp:masterfrom
peterishakvr12:master
Open

[fix] Auto-fill organization from master subnet in SubnetDivisionRule#1275
peterishakvr12 wants to merge 3 commits intoopenwisp:masterfrom
peterishakvr12:master

Conversation

@peterishakvr12
Copy link
Copy Markdown

@peterishakvr12 peterishakvr12 commented Mar 14, 2026

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

Closes #844

Description of Changes

When a subnet has an organization set, the SubnetDivisionRule
should automatically inherit the same organization at model level.

Added auto-fill logic in the clean() method of
AbstractSubnetDivisionRule to set the organization from the
master subnet if not already set.

Screenshot

No UI changes, backend model fix only.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 14, 2026

📝 Walkthrough

Walkthrough

Added logic to AbstractSubnetDivisionRule.clean() that, when master_subnet_id is present and the related master_subnet has an organization, auto-assigns that organization_id to the current instance if its organization_id is unset. This assignment occurs before calling super().clean(), so existing validation and control flow remain unchanged.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Bug Fixes ❌ Error PR lacks regression test required for bug fix validation; review comments explicitly request test addition for organization inheritance. Add regression test verifying organization_id auto-fill from master_subnet in clean() method, ensuring test fails without the fix.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title follows the required format with [fix] type prefix and clearly describes the main change: auto-filling organization from master subnet in SubnetDivisionRule.
Description check ✅ Passed The description covers the main sections: checklist items, issue reference (#844), and a clear description of changes. However, manual testing and test case updates are not marked as complete.
Linked Issues check ✅ Passed The PR implements the model-level auto-fill logic for organization in AbstractSubnetDivisionRule.clean() as required by issue #844, addressing the automatic inheritance requirement.
Out of Scope Changes check ✅ Passed The changes are focused solely on adding auto-fill logic for organization_id in AbstractSubnetDivisionRule.clean(), which is directly aligned with issue #844 objectives and contains no out-of-scope modifications.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@openwisp_controller/subnet_division/base/models.py`:
- Around line 72-78: Fix the inconsistent indentation in the if statement around
master_subnet_id/master_subnet.organization and align the conditions per PEP8,
and switch the FK existence check from checking self.organization (which
triggers a potential DB access) to checking self.organization_id; when
populating the field prefer assigning the id (set self.organization_id =
self.master_subnet.organization_id) instead of touching self.organization to
avoid an extra query. Ensure the conditional uses aligned parentheses and
consistent indentation and update the assignment to use organization_id to
prevent unnecessary DB lookups.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0e294c0d-b592-4d40-bb20-7c03dcdc529e

📥 Commits

Reviewing files that changed from the base of the PR and between d203490 and e27d40b.

📒 Files selected for processing (1)
  • openwisp_controller/subnet_division/base/models.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=5.2.0
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2026-01-15T15:05:49.557Z
Learnt from: DragnEmperor
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/config/management/commands/clear_last_ip.py:38-42
Timestamp: 2026-01-15T15:05:49.557Z
Learning: In Django projects, when using select_related() to traverse relations (for example, select_related("organization__config_settings")), the traversed relation must not be deferred. If you also use .only() in the same query, include the relation name or FK field (e.g., "organization" or "organization_id") in the .only() list to avoid the error "Field X cannot be both deferred and traversed using select_related at the same time." Apply this guideline to Django code in openwisp_controller/config/management/commands/clear_last_ip.py and similar modules by ensuring any select_related with an accompanying only() includes the related field names to prevent deferred/traversed conflicts.

Applied to files:

  • openwisp_controller/subnet_division/base/models.py
📚 Learning: 2026-02-17T19:13:10.088Z
Learnt from: nemesifier
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/config/whois/commands.py:0-0
Timestamp: 2026-02-17T19:13:10.088Z
Learning: In reviews for the openwisp/openwisp-controller repository, do not propose changes based on Ruff warnings. The project does not use Ruff as its linter; ignore Ruff-related suggestions and follow the repository’s established linting and configuration rules. This guidance applies to all Python files under the openwisp_controller directory.

Applied to files:

  • openwisp_controller/subnet_division/base/models.py
📚 Learning: 2026-01-15T15:07:17.354Z
Learnt from: DragnEmperor
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/geo/estimated_location/tests/tests.py:172-175
Timestamp: 2026-01-15T15:07:17.354Z
Learning: In this repository, flake8 enforces E501 (line too long) via setup.cfg (max-line-length = 88) while ruff ignores E501 via ruff.toml. Therefore, use '# noqa: E501' on lines that intentionally exceed 88 characters to satisfy flake8 without affecting ruff checks. This applies to Python files across the project (any .py) and is relevant for tests as well. Use sparingly and only where breaking lines is not feasible without hurting readability or functionality.

Applied to files:

  • openwisp_controller/subnet_division/base/models.py
🔇 Additional comments (1)
openwisp_controller/subnet_division/base/models.py (1)

79-85: LGTM!

The placement of the auto-fill logic before super().clean() and the existing validations is correct. The existing validation at lines 150-156 will still properly catch mismatches if a user explicitly sets a different organization than the master subnet's organization.

@peterishakvr12
Copy link
Copy Markdown
Author

Hi @nemesifier, I'm Peter, a Python/Django backend developer
preparing for GSoC 2026. I noticed issue #844 was open and
implemented the fix to auto-fill the organization field at
model level in the clean() method.

Please let me know if any changes are needed. I'm happy to
update the PR based on your feedback!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@openwisp_controller/subnet_division/base/models.py`:
- Around line 71-78: In the clean() method, avoid touching the related
Organization object; check self.master_subnet_id and
self.master_subnet_organization_id (or use self.master_subnet.organization_id)
instead of accessing self.master_subnet.organization, and assign the ID to
self.organization_id rather than setting self.organization so you don’t trigger
a DB fetch—update the conditional to test self.master_subnet.organization_id (or
fetch master_subnet_id relation) and set self.organization_id = that value when
self.organization_id is empty.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 039eb2da-664a-44f4-a138-fc19016609f5

📥 Commits

Reviewing files that changed from the base of the PR and between e27d40b and 1d81dd8.

📒 Files selected for processing (1)
  • openwisp_controller/subnet_division/base/models.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.13 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.2.0
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2026-01-15T15:05:49.557Z
Learnt from: DragnEmperor
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/config/management/commands/clear_last_ip.py:38-42
Timestamp: 2026-01-15T15:05:49.557Z
Learning: In Django projects, when using select_related() to traverse relations (for example, select_related("organization__config_settings")), the traversed relation must not be deferred. If you also use .only() in the same query, include the relation name or FK field (e.g., "organization" or "organization_id") in the .only() list to avoid the error "Field X cannot be both deferred and traversed using select_related at the same time." Apply this guideline to Django code in openwisp_controller/config/management/commands/clear_last_ip.py and similar modules by ensuring any select_related with an accompanying only() includes the related field names to prevent deferred/traversed conflicts.

Applied to files:

  • openwisp_controller/subnet_division/base/models.py
📚 Learning: 2026-02-17T19:13:10.088Z
Learnt from: nemesifier
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/config/whois/commands.py:0-0
Timestamp: 2026-02-17T19:13:10.088Z
Learning: In reviews for the openwisp/openwisp-controller repository, do not propose changes based on Ruff warnings. The project does not use Ruff as its linter; ignore Ruff-related suggestions and follow the repository’s established linting and configuration rules. This guidance applies to all Python files under the openwisp_controller directory.

Applied to files:

  • openwisp_controller/subnet_division/base/models.py
📚 Learning: 2026-01-15T15:07:17.354Z
Learnt from: DragnEmperor
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/geo/estimated_location/tests/tests.py:172-175
Timestamp: 2026-01-15T15:07:17.354Z
Learning: In this repository, flake8 enforces E501 (line too long) via setup.cfg (max-line-length = 88) while ruff ignores E501 via ruff.toml. Therefore, use '# noqa: E501' on lines that intentionally exceed 88 characters to satisfy flake8 without affecting ruff checks. This applies to Python files across the project (any .py) and is relevant for tests as well. Use sparingly and only where breaking lines is not feasible without hurting readability or functionality.

Applied to files:

  • openwisp_controller/subnet_division/base/models.py

@coveralls
Copy link
Copy Markdown

coveralls commented Mar 14, 2026

Coverage Status

coverage: 98.658% (-0.01%) from 98.672%
when pulling cfffbcb on peterishakvr12:master
into d203490 on openwisp:master.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@openwisp_controller/subnet_division/base/models.py`:
- Around line 72-79: Add a model test that creates a master_subnet with
organization_id set and a child subnet/instance with master_subnet assigned and
organization_id empty, then call full_clean() (so clean() runs before
validation) and assert that instance.organization_id equals
master_subnet.organization_id and no ValidationError is raised; reference the
model's clean() method and the fields master_subnet and organization_id when
locating the code to test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 06d97ae6-b18c-4e2a-bf98-6acff036f035

📥 Commits

Reviewing files that changed from the base of the PR and between 1d81dd8 and cfffbcb.

📒 Files selected for processing (1)
  • openwisp_controller/subnet_division/base/models.py
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: Python==3.11 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=4.2.0
  • GitHub Check: Python==3.10 | django~=5.1.0
  • GitHub Check: Python==3.12 | django~=5.2.0
  • GitHub Check: Python==3.12 | django~=4.2.0
  • GitHub Check: Python==3.12 | django~=5.1.0
  • GitHub Check: Python==3.11 | django~=5.2.0
  • GitHub Check: Python==3.13 | django~=5.1.0
  • GitHub Check: Python==3.10 | django~=5.2.0
  • GitHub Check: Python==3.13 | django~=5.2.0
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2026-01-15T15:05:49.557Z
Learnt from: DragnEmperor
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/config/management/commands/clear_last_ip.py:38-42
Timestamp: 2026-01-15T15:05:49.557Z
Learning: In Django projects, when using select_related() to traverse relations (for example, select_related("organization__config_settings")), the traversed relation must not be deferred. If you also use .only() in the same query, include the relation name or FK field (e.g., "organization" or "organization_id") in the .only() list to avoid the error "Field X cannot be both deferred and traversed using select_related at the same time." Apply this guideline to Django code in openwisp_controller/config/management/commands/clear_last_ip.py and similar modules by ensuring any select_related with an accompanying only() includes the related field names to prevent deferred/traversed conflicts.

Applied to files:

  • openwisp_controller/subnet_division/base/models.py
📚 Learning: 2026-02-17T19:13:10.088Z
Learnt from: nemesifier
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/config/whois/commands.py:0-0
Timestamp: 2026-02-17T19:13:10.088Z
Learning: In reviews for the openwisp/openwisp-controller repository, do not propose changes based on Ruff warnings. The project does not use Ruff as its linter; ignore Ruff-related suggestions and follow the repository’s established linting and configuration rules. This guidance applies to all Python files under the openwisp_controller directory.

Applied to files:

  • openwisp_controller/subnet_division/base/models.py
📚 Learning: 2026-01-15T15:07:17.354Z
Learnt from: DragnEmperor
Repo: openwisp/openwisp-controller PR: 1175
File: openwisp_controller/geo/estimated_location/tests/tests.py:172-175
Timestamp: 2026-01-15T15:07:17.354Z
Learning: In this repository, flake8 enforces E501 (line too long) via setup.cfg (max-line-length = 88) while ruff ignores E501 via ruff.toml. Therefore, use '# noqa: E501' on lines that intentionally exceed 88 characters to satisfy flake8 without affecting ruff checks. This applies to Python files across the project (any .py) and is relevant for tests as well. Use sparingly and only where breaking lines is not feasible without hurting readability or functionality.

Applied to files:

  • openwisp_controller/subnet_division/base/models.py
🔇 Additional comments (1)
openwisp_controller/subnet_division/base/models.py (1)

72-79: Auto-fill in clean() is implemented correctly and with the right FK-id usage.

Line 75-Line 78 correctly derive and assign organization_id using _id fields, and the assignment runs before super().clean() as expected.

Comment on lines +72 to 79
# Auto-fill organization from master subnet
if (
self.master_subnet_id
and self.master_subnet.organization_id is not None
and not self.organization_id
):
self.organization_id = self.master_subnet.organization_id
super().clean()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Add a regression test for the new organization inheritance branch.

Please add a model test that verifies: when master_subnet.organization_id is set and organization_id is empty, clean() sets organization_id before validation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openwisp_controller/subnet_division/base/models.py` around lines 72 - 79, Add
a model test that creates a master_subnet with organization_id set and a child
subnet/instance with master_subnet assigned and organization_id empty, then call
full_clean() (so clean() runs before validation) and assert that
instance.organization_id equals master_subnet.organization_id and no
ValidationError is raised; reference the model's clean() method and the fields
master_subnet and organization_id when locating the code to test.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[change:ux] Show subnet division rule organization field only if subnet organization field is set to shared

2 participants