From ce52aa25024636d656e343785d3f0880af4bc43a Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 6 Feb 2025 17:30:31 +0100 Subject: [PATCH] remove many to many relationship between ModelLog and Users --- sync/admin.py | 10 +++++----- sync/migrations/0001_initial.py | 12 ++++++++---- sync/migrations/0002_alter_modellog_date.py | 18 ------------------ sync/models/model_log.py | 10 ++++++++-- sync/signals.py | 18 +++++++++--------- sync/views.py | 4 ++-- 6 files changed, 32 insertions(+), 40 deletions(-) delete mode 100644 sync/migrations/0002_alter_modellog_date.py diff --git a/sync/admin.py b/sync/admin.py index f1d4ac1..33e702c 100644 --- a/sync/admin.py +++ b/sync/admin.py @@ -20,14 +20,14 @@ class SyncedObjectAdmin(admin.ModelAdmin): queryset.delete() class ModelLogAdmin(admin.ModelAdmin): - list_display = ['id', 'get_users', 'formatted_time', 'operation', 'model_id', 'model_name', 'count'] - list_filter = ['users', 'operation', 'model_name'] + list_display = ['user', 'formatted_time', 'operation', 'model_id', 'model_name', 'count'] + list_filter = ['user', 'operation', 'model_name'] ordering = ['-date'] search_fields = ['model_id'] - @admin.display(description='Users') - def get_users(self, obj): - return ", ".join([str(item) for item in obj.users.all()]) + # @admin.display(description='Users') + # def get_users(self, obj): + # return ", ".join([str(item) for item in obj.users.all()]) class DataAccessAdmin(SyncedObjectAdmin): list_display = ['related_user', 'get_shared_users', 'model_name', 'model_id'] diff --git a/sync/migrations/0001_initial.py b/sync/migrations/0001_initial.py index 62ff842..21dfbe2 100644 --- a/sync/migrations/0001_initial.py +++ b/sync/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1 on 2025-02-06 11:23 +# Generated by Django 5.1 on 2025-02-06 16:26 import django.db.models.deletion import django.utils.timezone @@ -36,15 +36,19 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ModelLog', fields=[ - ('id', models.BigAutoField(primary_key=True, serialize=False)), + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('model_id', models.UUIDField()), ('operation', models.CharField(choices=[('POST', 'POST'), ('PUT', 'PUT'), ('DELETE', 'DELETE'), ('GRANT_ACCESS', 'GRANT_ACCESS'), ('REVOKE_ACCESS', 'REVOKE_ACCESS')], max_length=50)), - ('date', models.DateTimeField()), + ('date', models.DateTimeField(auto_now_add=True)), ('model_name', models.CharField(max_length=50)), ('store_id', models.CharField(blank=True, max_length=200, null=True)), ('device_id', models.CharField(blank=True, max_length=200, null=True)), ('count', models.IntegerField(default=0)), - ('users', models.ManyToManyField(blank=True, related_name='model_logs', to=settings.AUTH_USER_MODEL)), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='model_logs', to=settings.AUTH_USER_MODEL)), ], + options={ + 'ordering': ['-date'], + 'indexes': [models.Index(fields=['date', 'user'], name='sync_modell_date_2bc081_idx'), models.Index(fields=['date', 'user', 'device_id'], name='sync_modell_date_77b4d0_idx')], + }, ), ] diff --git a/sync/migrations/0002_alter_modellog_date.py b/sync/migrations/0002_alter_modellog_date.py deleted file mode 100644 index d82580d..0000000 --- a/sync/migrations/0002_alter_modellog_date.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 5.1 on 2025-02-06 13:13 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('sync', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='modellog', - name='date', - field=models.DateTimeField(auto_now_add=True), - ), - ] diff --git a/sync/models/model_log.py b/sync/models/model_log.py index c0571c4..db1e96d 100644 --- a/sync/models/model_log.py +++ b/sync/models/model_log.py @@ -2,6 +2,7 @@ from django.db import models from django.conf import settings import uuid +from tkinter.constants import CASCADE class ModelOperation(models.TextChoices): @@ -13,9 +14,10 @@ class ModelOperation(models.TextChoices): class ModelLog(models.Model): # id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=True) - id = models.BigAutoField(primary_key=True) + # id = models.BigAutoField(primary_key=True) - users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='model_logs', blank=True) + # users = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='model_logs', blank=True) + user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='model_logs') model_id = models.UUIDField() operation = models.CharField(choices=ModelOperation.choices, max_length=50) date = models.DateTimeField(auto_now_add=True) @@ -26,6 +28,10 @@ class ModelLog(models.Model): class Meta: ordering = ['-date'] + indexes = [ + models.Index(fields=['date', 'user']), + models.Index(fields=['date', 'user', 'device_id']), + ] def formatted_time(self): return self.date.strftime('%H:%M:%S.%f') diff --git a/sync/signals.py b/sync/signals.py index 87f4e9b..d6d64de 100644 --- a/sync/signals.py +++ b/sync/signals.py @@ -121,15 +121,15 @@ def save_model_log_if_possible(instance, signal, created, device_id): def save_model_log(users, model_operation, model_name, model_id, store_id, device_id): with transaction.atomic(): - model_log = ModelLog() - model_log.operation = model_operation - model_log.model_name = model_name - model_log.model_id = model_id - model_log.store_id = store_id - model_log.device_id = device_id - # model_log.date = timezone.now() - model_log.save() - model_log.users.set(users) + for user in users: + model_log = ModelLog() + model_log.user = user + model_log.operation = model_operation + model_log.model_name = model_name + model_log.model_id = model_id + model_log.store_id = store_id + model_log.device_id = device_id + model_log.save() # print(f'ML users = {len(users)}') # existing_log = ModelLog.objects.filter(users__in=users, model_id=model_id, operation=model_operation).first() diff --git a/sync/views.py b/sync/views.py index 76e9187..cb5f9ad 100644 --- a/sync/views.py +++ b/sync/views.py @@ -268,10 +268,10 @@ class SynchronizationApi(HierarchyApiView): return Response(response_data, status=status.HTTP_200_OK) def query_model_logs(self, last_update, user, device_id): - log_query = Q(date__gt=last_update, users=user) + log_query = Q(date__gt=last_update, user=user) if device_id: log_query &= ~Q(device_id=device_id) # exclude query - return ModelLog.objects.filter(log_query).order_by('date') + return ModelLog.objects.filter(log_query) class UserDataAccessApi(HierarchyApiView): permission_classes = [IsAuthenticated]