1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #12129: Enable automatic synchronization of objects when DataFiles are updated (#12262)

* Closes #12129: Enable automatic synchronization of objects when DataFiles are updated

* Cleanup
This commit is contained in:
Jeremy Stretch
2023-04-17 10:35:17 -04:00
committed by GitHub
parent d470848b29
commit 8b040ff930
11 changed files with 120 additions and 17 deletions

View File

@@ -80,12 +80,12 @@ class ManagedFileForm(SyncedDataMixin, NetBoxModelForm):
fieldsets = (
('File Upload', ('upload_file',)),
('Data Source', ('data_source', 'data_file')),
('Data Source', ('data_source', 'data_file', 'auto_sync_enabled')),
)
class Meta:
model = ManagedFile
fields = ('data_source', 'data_file')
fields = ('data_source', 'data_file', 'auto_sync_enabled')
def clean(self):
super().clean()

View File

@@ -63,4 +63,21 @@ class Migration(migrations.Migration):
model_name='datafile',
index=models.Index(fields=['source', 'path'], name='core_datafile_source_path'),
),
migrations.CreateModel(
name='AutoSyncRecord',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
('object_id', models.PositiveBigIntegerField()),
('datafile', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='core.datafile')),
('object_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='contenttypes.contenttype')),
],
),
migrations.AddIndex(
model_name='autosyncrecord',
index=models.Index(fields=['object_type', 'object_id'], name='core_autosy_object__c17bac_idx'),
),
migrations.AddConstraint(
model_name='autosyncrecord',
constraint=models.UniqueConstraint(fields=('object_type', 'object_id'), name='core_autosyncrecord_object'),
),
]

View File

@@ -23,6 +23,7 @@ class Migration(migrations.Migration):
('file_path', models.FilePathField(editable=False)),
('data_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile')),
('data_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource')),
('auto_sync_enabled', models.BooleanField(default=False)),
],
options={
'ordering': ('file_root', 'file_path'),

View File

@@ -5,7 +5,8 @@ from fnmatch import fnmatchcase
from urllib.parse import urlparse
from django.conf import settings
from django.contrib.contenttypes.fields import GenericRelation
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator
from django.db import models
@@ -25,6 +26,7 @@ from ..signals import post_sync, pre_sync
from .jobs import Job
__all__ = (
'AutoSyncRecord',
'DataFile',
'DataSource',
)
@@ -327,3 +329,35 @@ class DataFile(models.Model):
with open(path, 'wb+') as new_file:
new_file.write(self.data)
class AutoSyncRecord(models.Model):
"""
Maps a DataFile to a synced object for efficient automatic updating.
"""
datafile = models.ForeignKey(
to=DataFile,
on_delete=models.CASCADE,
related_name='+'
)
object_type = models.ForeignKey(
to=ContentType,
on_delete=models.CASCADE,
related_name='+'
)
object_id = models.PositiveBigIntegerField()
object = GenericForeignKey(
ct_field='object_type',
fk_field='object_id'
)
class Meta:
constraints = (
models.UniqueConstraint(
fields=('object_type', 'object_id'),
name='%(app_label)s_%(class)s_object'
),
)
indexes = (
models.Index(fields=('object_type', 'object_id')),
)

View File

@@ -1,4 +1,4 @@
import django.dispatch
from django.dispatch import Signal, receiver
__all__ = (
'post_sync',
@@ -6,5 +6,16 @@ __all__ = (
)
# DataSource signals
pre_sync = django.dispatch.Signal()
post_sync = django.dispatch.Signal()
pre_sync = Signal()
post_sync = Signal()
@receiver(post_sync)
def auto_sync(instance, **kwargs):
"""
Automatically synchronize any DataFiles with AutoSyncRecords after synchronizing a DataSource.
"""
from .models import AutoSyncRecord
for autosync in AutoSyncRecord.objects.filter(datafile__source=instance).prefetch_related('object'):
autosync.object.sync(save=True)