Adds related_user to BaseModel

sync
Laurent 11 months ago
parent 5008f5588c
commit 9ce87672d9
  1. 4
      sync/admin.py
  2. 30
      sync/migrations/0002_remove_dataaccess_owner_dataaccess_related_user_and_more.py
  3. 6
      sync/models/base.py
  4. 4
      sync/models/data_access.py
  5. 70
      sync/signals.py
  6. 2
      sync/views.py
  7. 165
      tournaments/migrations/0106_club_related_user_court_related_user_and_more.py

@ -20,8 +20,8 @@ class ModelLogAdmin(admin.ModelAdmin):
return ", ".join([str(item) for item in obj.users.all()]) return ", ".join([str(item) for item in obj.users.all()])
class DataAccessAdmin(AutoUpdateAdmin): class DataAccessAdmin(AutoUpdateAdmin):
list_display = ['owner', 'get_shared_users', 'model_name', 'model_id'] list_display = ['related_user', 'get_shared_users', 'model_name', 'model_id']
list_filter = ['owner', 'shared_with'] list_filter = ['related_user', 'shared_with']
ordering = ['-granted_at'] ordering = ['-granted_at']
@admin.display(description='Shared with') @admin.display(description='Shared with')

@ -0,0 +1,30 @@
# Generated by Django 5.1 on 2024-12-10 15:12
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('sync', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.RemoveField(
model_name='dataaccess',
name='owner',
),
migrations.AddField(
model_name='dataaccess',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='dataaccess',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
]

@ -1,12 +1,13 @@
from django.db import models from django.db import models
from django.utils.timezone import now from django.utils.timezone import now
from typing import List, Set
from django.conf import settings from django.conf import settings
from typing import List, Set
class BaseModel(models.Model): class BaseModel(models.Model):
creation_date = models.DateTimeField(default=now, editable=False) creation_date = models.DateTimeField(default=now, editable=False)
last_update = models.DateTimeField(default=now) last_update = models.DateTimeField(default=now)
last_updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL) related_user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL, related_name='+')
last_updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL, related_name='+')
class Meta: class Meta:
abstract = True abstract = True
@ -57,7 +58,6 @@ class BaseModel(models.Model):
return parents return parents
def get_recursive_children(self, processed_objects: Set = None) -> List: def get_recursive_children(self, processed_objects: Set = None) -> List:
""" """
Recursively get all children objects through the hierarchy Recursively get all children objects through the hierarchy

@ -1,6 +1,6 @@
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from django.apps import apps # from django.apps import apps
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings from django.conf import settings
@ -11,7 +11,7 @@ from . import ModelLog, SideStoreModel, BaseModel
class DataAccess(BaseModel): class DataAccess(BaseModel):
id = models.UUIDField(primary_key=True, default=uuid.uuid4) id = models.UUIDField(primary_key=True, default=uuid.uuid4)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='owned_data', on_delete=models.CASCADE) # owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='owned_data', on_delete=models.CASCADE)
shared_with = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='shared_data') shared_with = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='shared_data')
model_name = models.CharField(max_length=50) model_name = models.CharField(max_length=50)
model_id = models.UUIDField() model_id = models.UUIDField()

@ -54,13 +54,14 @@ def notify_impacted_users(instance, signal):
websocket_sender.send_user_message(user_id) websocket_sender.send_user_message(user_id)
# send_user_message(user_id) # send_user_message(user_id)
def save_model_log_if_possible(instance, signal, created): def save_model_log_if_possible(instance, signal, created):
if isinstance(instance, User): if isinstance(instance, User):
user = instance users = {instance}
else: else:
user = instance.last_updated_by users = related_users(instance)
if user: if users:
if signal == post_save or signal == pre_save: if signal == post_save or signal == pre_save:
if created: if created:
operation = ModelOperation.POST operation = ModelOperation.POST
@ -77,16 +78,6 @@ def save_model_log_if_possible(instance, signal, created):
if operation == ModelOperation.DELETE: # delete now unnecessary logs if operation == ModelOperation.DELETE: # delete now unnecessary logs
ModelLog.objects.filter(model_id=instance.id).delete() ModelLog.objects.filter(model_id=instance.id).delete()
users = {user}
if isinstance(instance, BaseModel):
data_access_list = related_data_access(instance)
for data_access in data_access_list:
users.add(data_access.owner)
users.update(data_access.shared_with.all())
if isinstance(instance, DataAccess):
users.add(instance.owner)
users.update(instance.shared_with.all())
user_ids = [user.id for user in users] user_ids = [user.id for user in users]
print(f'users to notify: {user_ids}') print(f'users to notify: {user_ids}')
@ -115,12 +106,6 @@ def save_model_log(users, model_operation, model_name, model_id, store_id):
model_log.save() model_log.save()
model_log.users.set(users) model_log.users.set(users)
def related_data_access(instance):
related_instances = instance.related_instances()
related_ids = [ri.id for ri in related_instances]
related_ids.append(instance.id)
return DataAccess.objects.filter(model_id__in=related_ids)
def delete_data_access_if_necessary(model_id): def delete_data_access_if_necessary(model_id):
DataAccess.objects.filter(model_id=model_id).delete() DataAccess.objects.filter(model_id=model_id).delete()
@ -138,31 +123,34 @@ def handle_shared_with_changes(sender, instance, action, pk_set, **kwargs):
websocket_sender.send_user_message(user_id) websocket_sender.send_user_message(user_id)
# send_user_message(user_id) # send_user_message(user_id)
# def send_user_message(user_id): @receiver(pre_delete, sender=DataAccess)
def revoke_access_after_delete(sender, instance, **kwargs):
instance.create_revoke_access_log()
# if not hasattr(send_user_message, '_buffer'): def related_users(instance):
# send_user_message._buffer = set() users = set()
# send_user_message._timer = None if isinstance(instance, User):
users.add(instance)
elif isinstance(instance, BaseModel):
users.add(instance.related_user)
users.add(instance.last_updated_by)
# send_user_message._buffer.add(user_id) related_instances = instance.related_instances()
related_users = [ri.related_user for ri in related_instances if isinstance(ri, BaseModel)]
users.update(related_users)
# if send_user_message._timer: data_access_list = related_data_access(instance, related_instances)
# send_user_message._timer.cancel() for data_access in data_access_list:
users.add(data_access.related_user)
users.update(data_access.shared_with.all())
# def send_buffered_messages(): if isinstance(instance, DataAccess):
# channel_layer = get_channel_layer() users.update(instance.shared_with.all())
# for buffered_id in send_user_message._buffer:
# group_name = f"sync_{buffered_id}"
# print(f">>> send to group {group_name}")
# async_to_sync(channel_layer.group_send)(
# group_name, {"type": "sync.update", "message": "hello"}
# )
# send_user_message._buffer.clear()
# send_user_message._timer = None
# send_user_message._timer = Timer(0.1, send_buffered_messages) return {user for user in users if user is not None}
# send_user_message._timer.start()
@receiver(pre_delete, sender=DataAccess) def related_data_access(instance, related_instances):
def revoke_access_after_delete(sender, instance, **kwargs): # related_instances = instance.related_instances()
instance.create_revoke_access_log() related_ids = [ri.id for ri in related_instances]
related_ids.append(instance.id)
return DataAccess.objects.filter(model_id__in=related_ids)

@ -313,5 +313,5 @@ class DataAccessViewSet(viewsets.ModelViewSet):
def get_queryset(self): def get_queryset(self):
if self.request.user: if self.request.user:
return self.queryset.filter(Q(owner=self.request.user) | Q(shared_with__in=[self.request.user])) return self.queryset.filter(Q(related_user=self.request.user) | Q(shared_with__in=[self.request.user]))
return [] return []

@ -0,0 +1,165 @@
# Generated by Django 5.1 on 2024-12-10 15:12
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tournaments', '0105_rename_referees_customuser_agents'),
]
operations = [
migrations.AddField(
model_name='club',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='court',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='dateinterval',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='devicetoken',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='event',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='failedapicall',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='groupstage',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='log',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='match',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='playerregistration',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='purchase',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='round',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='teamregistration',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='teamscore',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='tournament',
name='related_user',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='club',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='court',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='dateinterval',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='devicetoken',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='event',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='failedapicall',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='groupstage',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='log',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='match',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='playerregistration',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='purchase',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='round',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='teamregistration',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='teamscore',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='tournament',
name='last_updated_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL),
),
]
Loading…
Cancel
Save