Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
820bb32
NPL-374 Add Bookmark mixin
arthanson Jul 9, 2025
3e48069
NPL-374 Add Bookmark mixin for add inline
arthanson Jul 9, 2025
b047f15
NPL-374 Add Bookmark mixin
arthanson Jul 9, 2025
40d0a1e
NPL-374 Add Bookmark mixin
arthanson Jul 14, 2025
f76344e
Merge branch 'main' into NPL-374-bookmark
arthanson Jul 14, 2025
7128a0f
NPL-374 Add tags
arthanson Jul 14, 2025
46fbdb8
NPL-374 fix url routing
arthanson Jul 14, 2025
df033c4
NPL-374 fix for both cases of bookmark
arthanson Jul 14, 2025
dd0baa5
Merge branch 'main' into NPL-374-bookmark-2
arthanson Jul 15, 2025
03d5da5
NPL-374 cleanup
arthanson Jul 15, 2025
ec9bda7
NPL-374 cleanup
arthanson Jul 15, 2025
3db27bb
NPL-374 cleanup
arthanson Jul 15, 2025
7deb04c
NPL-374 cleanup
arthanson Jul 15, 2025
fed29dc
NPL-374 cleanup
arthanson Jul 15, 2025
1ffc480
NPL-374 fix subscribe button
arthanson Jul 15, 2025
131740e
NPL-374 fix clone button
arthanson Jul 15, 2025
c75848a
NPL-374 fix eventsrulesmixin button
arthanson Jul 15, 2025
60409e1
NPL-374 changelogging mixin
arthanson Jul 15, 2025
95ec125
Merge branch 'main' into NPL-374-bookmark-2
arthanson Jul 17, 2025
21caffb
NPL-374 move tags
arthanson Jul 17, 2025
5313595
NPL-374 fix tagging with ABC
arthanson Jul 21, 2025
0e256c4
merge main
arthanson Jul 21, 2025
a301b46
fix detail view
arthanson Jul 21, 2025
69a2281
multiple through models
arthanson Jul 21, 2025
b86c3b1
fix ruff errors
arthanson Jul 21, 2025
67e6e52
clone fields
arthanson Jul 21, 2025
465f71e
add custom links
arthanson Jul 22, 2025
e18b7ad
fix multi-object fields creation
arthanson Jul 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions netbox_custom_objects/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,5 @@ class CustomObjectsPluginConfig(PluginConfig):
required_settings = []
template_extensions = "template_content.template_extensions"

# def get_model(self, model_name, require_ready=True):
# if require_ready:
# self.apps.check_models_ready()
# else:
# self.apps.check_apps_ready()
#
# if model_name.lower() in self.models:
# return self.models[model_name.lower()]
#
# from .models import CustomObjectType
# if "table" not in model_name.lower() or "model" not in model_name.lower():
# raise LookupError(
# "App '%s' doesn't have a '%s' model." % (self.label, model_name)
# )
#
# custom_object_type_id = int(model_name.replace("table", "").replace("model", ""))
#
# try:
# obj = CustomObjectType.objects.get(pk=custom_object_type_id)
# except CustomObjectType.DoesNotExist:
# raise LookupError(
# "App '%s' doesn't have a '%s' model." % (self.label, model_name)
# )
# return obj.get_model()


config = CustomObjectsPluginConfig
3 changes: 1 addition & 2 deletions netbox_custom_objects/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from rest_framework.routers import APIRootView
from rest_framework.viewsets import ModelViewSet

from netbox_custom_objects.models import CustomObject, CustomObjectType, CustomObjectTypeField
from netbox_custom_objects.models import CustomObjectType, CustomObjectTypeField

from . import serializers

Expand All @@ -18,7 +18,6 @@ class CustomObjectTypeViewSet(ModelViewSet):


class CustomObjectViewSet(ModelViewSet):
queryset = CustomObject.objects.all()
serializer_class = serializers.CustomObjectSerializer
model = None

Expand Down
50 changes: 37 additions & 13 deletions netbox_custom_objects/field_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,16 +611,15 @@ def get_through_model(self, field, model=None):
and field.custom_object_type.id == custom_object_type_id
)

# Use the actual model if provided, otherwise use string reference
source_model = model if model else "netbox_custom_objects.CustomObject"

attrs = {
"__module__": "netbox_custom_objects.models",
"Meta": meta,
"id": models.AutoField(primary_key=True),
"source": models.ForeignKey(
(
"self"
if is_self_referential
else (model or "netbox_custom_objects.CustomObject")
),
source_model,
on_delete=models.CASCADE,
related_name="+",
db_column="source_id",
Expand Down Expand Up @@ -652,6 +651,8 @@ def get_model_field(self, field, **kwargs):
and field.custom_object_type.id == custom_object_type_id
)

# For now, we'll create the through model with string references
# and resolve them later in after_model_generation
through = self.get_through_model(field)

# For self-referential fields, use 'self' as the target
Expand Down Expand Up @@ -694,8 +695,14 @@ def after_model_generation(self, instance, model, field_name):
if getattr(field, "_is_self_referential", False):
field.remote_field.model = model
through_model = field.remote_field.through
through_model._meta.get_field("target").remote_field.model = model
through_model._meta.get_field("target").related_model = model

# Update both source and target fields to point to the same model
source_field = through_model._meta.get_field("source")
target_field = through_model._meta.get_field("target")
source_field.remote_field.model = model
source_field.related_model = model
target_field.remote_field.model = model
target_field.related_model = model
return

content_type = ContentType.objects.get(pk=instance.related_object_type_id)
Expand All @@ -713,12 +720,19 @@ def after_model_generation(self, instance, model, field_name):
to_ct = f"{content_type.app_label}.{content_type.model}"
to_model = apps.get_model(to_ct)

# Update the M2M field's model references
# Update through model's fields
field.remote_field.model = to_model

# Update through model's target field
through_model = field.remote_field.through
source_field = through_model._meta.get_field("source")
target_field = through_model._meta.get_field("target")

# Source field should point to the current model
source_field.remote_field.model = model
source_field.related_model = model

# Target field should point to the related model
target_field.remote_field.model = to_model
target_field.related_model = to_model

Expand Down Expand Up @@ -751,15 +765,24 @@ def create_m2m_table(self, instance, model, field_name):

# Create the through model with actual model references
through = self.get_through_model(instance, model)
through._meta.get_field("target").remote_field.model = to_model
through._meta.get_field("target").related_model = to_model

# Update the through model's foreign key references
source_field = through._meta.get_field("source")
target_field = through._meta.get_field("target")

# Source field should point to the current model
source_field.remote_field.model = model
source_field.remote_field.field_name = model._meta.pk.name
source_field.related_model = model

# Target field should point to the related model
target_field.remote_field.model = to_model
target_field.remote_field.field_name = to_model._meta.pk.name
target_field.related_model = to_model

# Register the model with Django's app registry
apps = model._meta.apps

# if app_label is None:
# app_label = str(uuid.uuid4()) + "_database_table"
# apps = AppsProxy(dynamic_models=None, app_label=app_label)
try:
through_model = apps.get_model(APP_LABEL, instance.through_model_name)
except LookupError:
Expand All @@ -769,6 +792,7 @@ def create_m2m_table(self, instance, model, field_name):
# Update the M2M field's through model and target model
field.remote_field.through = through_model
field.remote_field.model = to_model
field.remote_field.field_name = to_model._meta.pk.name

# Create the through table
with connection.schema_editor() as schema_editor:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 5.2.2 on 2025-07-15 17:59

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("netbox_custom_objects", "0001_initial"),
]

operations = [
migrations.AddField(
model_name="customobject",
name="created",
field=models.DateTimeField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name="customobject",
name="last_updated",
field=models.DateTimeField(auto_now=True, null=True),
),
]
19 changes: 19 additions & 0 deletions netbox_custom_objects/migrations/0003_delete_customobject.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 5.2.2 on 2025-07-18 20:24

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
(
"netbox_custom_objects",
"0002_customobject_created_customobject_last_updated",
),
]

operations = [
migrations.DeleteModel(
name="CustomObject",
),
]
Loading