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 * Cleanup
This commit is contained in:
@@ -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()
|
||||
|
@@ -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'),
|
||||
),
|
||||
]
|
||||
|
@@ -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'),
|
||||
|
@@ -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')),
|
||||
)
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user