parent
2d2e17eb70
commit
41ba44df98
@ -0,0 +1,227 @@ |
|||||||
|
from django.db.models.fields.related_lookups import RelatedExact |
||||||
|
from rest_framework.views import APIView |
||||||
|
from rest_framework.permissions import IsAuthenticated |
||||||
|
from rest_framework.response import Response |
||||||
|
from rest_framework import status |
||||||
|
|
||||||
|
from django.apps import apps |
||||||
|
from django.utils import timezone |
||||||
|
from django.db.models import Q |
||||||
|
|
||||||
|
from collections import defaultdict |
||||||
|
|
||||||
|
from .utils import build_serializer_class, get_data, get_serialized_data |
||||||
|
|
||||||
|
from tournaments.models import ModelLog, DataAccess, BaseModel |
||||||
|
|
||||||
|
class DataApi(APIView): |
||||||
|
permission_classes = [IsAuthenticated] |
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs): |
||||||
|
|
||||||
|
# unfold content |
||||||
|
model_operation = request.data.get('operation') |
||||||
|
model_name = request.data.get('model_name') |
||||||
|
data = request.data.get('data') |
||||||
|
store_id = request.data.get('store_id') |
||||||
|
|
||||||
|
print(f"DataApi post > {model_operation} {model_name}") |
||||||
|
|
||||||
|
serializer_class = build_serializer_class(model_name) |
||||||
|
|
||||||
|
model = apps.get_model(app_label='tournaments', model_name=model_name) |
||||||
|
now = timezone.localtime(timezone.now()) |
||||||
|
try: |
||||||
|
data_id = data.get('id') |
||||||
|
# instance = model.objects.get(id=data_id) |
||||||
|
|
||||||
|
instance = get_data('tournaments', model_name, data_id) |
||||||
|
|
||||||
|
# update the possible data access objects with the current date |
||||||
|
|
||||||
|
if model_operation == 'DELETE': |
||||||
|
parent_model, parent_id = instance.get_parent_reference() |
||||||
|
return self.delete_and_save_log(request, data_id, model_operation, model_name, store_id, now) |
||||||
|
else: # PUT |
||||||
|
serializer = serializer_class(instance, data=data, context={'request': request}) |
||||||
|
if serializer.is_valid(): |
||||||
|
if instance.last_update <= serializer.validated_data.get('last_update'): |
||||||
|
print('>>> update') |
||||||
|
return self.save_and_create_log(request, serializer, model_operation, model_name, store_id, now) |
||||||
|
else: |
||||||
|
print('>>> return 203') |
||||||
|
return Response(serializer.data, status=status.HTTP_203_NON_AUTHORITATIVE_INFORMATION) |
||||||
|
else: |
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) |
||||||
|
except model.DoesNotExist: # POST |
||||||
|
print('>>> insert') |
||||||
|
serializer = serializer_class(data=data, context={'request': request}) |
||||||
|
if serializer.is_valid(): |
||||||
|
return self.save_and_create_log(request, serializer, model_operation, model_name, store_id, now) |
||||||
|
else: |
||||||
|
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) |
||||||
|
|
||||||
|
def save_and_create_log(self, request, serializer, model_operation, model_name, store_id, date): |
||||||
|
instance = serializer.save() |
||||||
|
|
||||||
|
self.create_and_save_model_log( |
||||||
|
user=request.user, |
||||||
|
model_operation=model_operation, |
||||||
|
model_name=model_name, |
||||||
|
model_id=instance.id, |
||||||
|
store_id=store_id, |
||||||
|
date=date |
||||||
|
) |
||||||
|
|
||||||
|
self.update_linked_data_access(instance, date) |
||||||
|
|
||||||
|
return Response(serializer.data, status=status.HTTP_201_CREATED) |
||||||
|
|
||||||
|
def delete_and_save_log(self, request, data_id, model_operation, model_name, store_id, date): |
||||||
|
|
||||||
|
instance = get_data('tournaments', model_name, data_id) |
||||||
|
self.update_linked_data_access(instance, date) |
||||||
|
|
||||||
|
instance.delete() |
||||||
|
|
||||||
|
# we delete all previous logs linked to the instance because they won't be needed anymore |
||||||
|
ModelLog.objects.filter(model_id=data_id).delete() |
||||||
|
|
||||||
|
self.create_and_save_model_log( |
||||||
|
user=request.user, |
||||||
|
model_operation=model_operation, |
||||||
|
model_name=model_name, |
||||||
|
model_id=data_id, |
||||||
|
store_id=store_id, |
||||||
|
date=date |
||||||
|
) |
||||||
|
|
||||||
|
return Response(status=status.HTTP_204_NO_CONTENT) |
||||||
|
|
||||||
|
def update_linked_data_access(self, instance, date): |
||||||
|
related_instances = instance.related_instances() |
||||||
|
related_ids = [ri.id for ri in instance.related_instances()] |
||||||
|
related_ids.append(instance.id) |
||||||
|
data_access_list = DataAccess.objects.filter(model_id__in=related_ids) |
||||||
|
|
||||||
|
for data_access in data_access_list: |
||||||
|
data_access.last_hierarchy_update = date |
||||||
|
data_access.save() |
||||||
|
|
||||||
|
def create_and_save_model_log(self, user, model_operation, model_name, model_id, store_id, date): |
||||||
|
model_log = ModelLog() |
||||||
|
model_log.user = user |
||||||
|
model_log.operation = model_operation |
||||||
|
model_log.date = date |
||||||
|
model_log.model_name = model_name |
||||||
|
model_log.model_id = model_id |
||||||
|
model_log.store_id = store_id |
||||||
|
model_log.save() |
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs): |
||||||
|
last_update = request.query_params.get('last_update') |
||||||
|
if not last_update: |
||||||
|
return Response({"error": "last_update parameter is required"}, status=status.HTTP_400_BAD_REQUEST) |
||||||
|
|
||||||
|
print(f'/data GET: {last_update}') |
||||||
|
|
||||||
|
logs = self.query_model_logs(last_update, request.user) |
||||||
|
|
||||||
|
updates = defaultdict(dict) |
||||||
|
deletions = defaultdict(list) |
||||||
|
|
||||||
|
print(f'>>> log count = {len(logs)}') |
||||||
|
|
||||||
|
for log in logs: |
||||||
|
if log.operation in ['POST', 'PUT']: |
||||||
|
data = get_serialized_data('tournaments', log.model_name, log.model_id) |
||||||
|
updates[log.model_name][log.model_id] = data |
||||||
|
elif log.operation == 'DELETE': |
||||||
|
deletions[log.model_name].append({'model_id': log.model_id, 'store_id': log.store_id}) |
||||||
|
elif log.operation == 'GRANT_ACCESS': |
||||||
|
|
||||||
|
model = apps.get_model('tournaments', model_name=log.model_name) |
||||||
|
instance = model.objects.get(id=log.model_id) |
||||||
|
serializer_class = build_serializer_class(log.model_name) |
||||||
|
serializer = serializer_class(instance) |
||||||
|
|
||||||
|
# data = get_serialized_data('tournaments', log.model_name, log.model_id) |
||||||
|
updates[log.model_name][log.model_id] = serializer.data |
||||||
|
# instance = model.objects.get(id=log.model_id) |
||||||
|
self.add_children_recursively(instance, updates) |
||||||
|
self.add_parents_recursively(instance, updates) |
||||||
|
elif log.operation == 'delete data access signal': |
||||||
|
print(f'revoke access {log.model_id} - {log.store_id}') |
||||||
|
deletions[log.model_name].append({'model_id': log.model_id, 'store_id': log.store_id}) |
||||||
|
|
||||||
|
# Convert updates dict to list for each model |
||||||
|
for model_name in updates: |
||||||
|
updates[model_name] = list(updates[model_name].values()) |
||||||
|
|
||||||
|
# Convert deletions set to list for each model |
||||||
|
for model_name in deletions: |
||||||
|
deletions[model_name] = deletions[model_name] |
||||||
|
|
||||||
|
response_data = { |
||||||
|
"updates": dict(updates), |
||||||
|
"deletions": dict(deletions) |
||||||
|
} |
||||||
|
|
||||||
|
return Response(response_data, status=status.HTTP_200_OK) |
||||||
|
|
||||||
|
def query_model_logs(self, last_update, user): |
||||||
|
try: |
||||||
|
last_update = timezone.datetime.fromisoformat(last_update) |
||||||
|
except ValueError: |
||||||
|
return Response({"error": f"Invalid date format for last_update: {last_update}"}, status=status.HTTP_400_BAD_REQUEST) |
||||||
|
|
||||||
|
# get recently modified DataAccess |
||||||
|
data_access_query = Q(last_hierarchy_update__gt=last_update) & (Q(shared_with__in=[user]) | Q(owner=user)) |
||||||
|
data_access_list = DataAccess.objects.filter(data_access_query) #.values_list('model_id', flat=True) |
||||||
|
|
||||||
|
print(f'>> da count = {len(data_access_list)}') |
||||||
|
|
||||||
|
# get ids of all recently updated related instances of each shared data |
||||||
|
model_ids = [] |
||||||
|
for data_access in data_access_list: |
||||||
|
instance = get_data('tournaments', data_access.model_name, data_access.model_id) |
||||||
|
related_instances = instance.related_instances() |
||||||
|
related_ids = [ri.id for ri in instance.related_instances() if ri.last_update > last_update] |
||||||
|
model_ids.extend(related_ids) |
||||||
|
model_ids.append(instance.id) |
||||||
|
|
||||||
|
# get all ModelLog list since the last_update, from the user and from the data he has access to |
||||||
|
log_query = Q(date__gt=last_update) & (Q(user=user) | Q(model_id__in=model_ids)) |
||||||
|
return ModelLog.objects.filter(log_query).order_by('date') |
||||||
|
|
||||||
|
def add_children_recursively(self, instance, updates): |
||||||
|
""" |
||||||
|
Recursively add all children of an instance to the updates dictionary. |
||||||
|
""" |
||||||
|
# print(f"Instance class: {instance.__class__}") |
||||||
|
child_models = instance.get_children_by_model() |
||||||
|
|
||||||
|
for child_model_name, children in child_models.items(): |
||||||
|
for child in children: |
||||||
|
if isinstance(child, BaseModel): |
||||||
|
serializer_class = build_serializer_class(child_model_name) |
||||||
|
serializer = serializer_class(child) |
||||||
|
updates[child_model_name][child.id] = serializer.data |
||||||
|
self.add_children_recursively(child, updates) |
||||||
|
|
||||||
|
def add_parents_recursively(self, instance, updates): |
||||||
|
parent_models = instance.get_parents_by_model() |
||||||
|
|
||||||
|
for parent_model_name, parent in parent_models.items(): |
||||||
|
# print(f'parent = {parent_model_name}') |
||||||
|
if isinstance(parent, BaseModel): |
||||||
|
serializer_class = build_serializer_class(parent_model_name) |
||||||
|
serializer = serializer_class(parent) |
||||||
|
updates[parent_model_name][parent.id] = serializer.data |
||||||
|
self.add_parents_recursively(parent, updates) |
||||||
|
|
||||||
|
# def get_data(self, model, log): |
||||||
|
# instance = model.objects.get(id=log.model_id) |
||||||
|
# serializer_class = build_serializer_class(log.model_name) |
||||||
|
# serializer = serializer_class(instance) |
||||||
|
# return serializer.data |
||||||
@ -0,0 +1,190 @@ |
|||||||
|
# Generated by Django 5.1 on 2024-11-12 16:41 |
||||||
|
|
||||||
|
import django.db.models.deletion |
||||||
|
from django.conf import settings |
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('tournaments', '0096_alter_modellog_operation_and_more'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='club', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='court', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='dateinterval', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='devicetoken', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='event', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='failedapicall', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='groupstage', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='log', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='match', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='playerregistration', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='purchase', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='round', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='teamregistration', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='teamscore', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='tournament', |
||||||
|
name='last_updated_by', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='club', |
||||||
|
name='creator', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='creator_clubs', to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='court', |
||||||
|
name='club', |
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='courts', to='tournaments.club'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='customuser', |
||||||
|
name='clubs', |
||||||
|
field=models.ManyToManyField(blank=True, related_name='creators', to='tournaments.club'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='dateinterval', |
||||||
|
name='event', |
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='date_intervals', to='tournaments.event'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='devicetoken', |
||||||
|
name='user', |
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='device_tokens', to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='event', |
||||||
|
name='club', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='events', to='tournaments.club'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='event', |
||||||
|
name='creator', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='events', to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='failedapicall', |
||||||
|
name='user', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='failed_api_calls', to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='groupstage', |
||||||
|
name='tournament', |
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='group_stages', to='tournaments.tournament'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='log', |
||||||
|
name='user', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='logs', to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='match', |
||||||
|
name='group_stage', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='matches', to='tournaments.groupstage'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='match', |
||||||
|
name='round', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='matches', to='tournaments.round'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='modellog', |
||||||
|
name='user', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='model_logs', to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='playerregistration', |
||||||
|
name='team_registration', |
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='player_registrations', to='tournaments.teamregistration'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='purchase', |
||||||
|
name='user', |
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='purchases', to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='round', |
||||||
|
name='tournament', |
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rounds', to='tournaments.tournament'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='teamregistration', |
||||||
|
name='group_stage', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='team_registrations', to='tournaments.groupstage'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='teamregistration', |
||||||
|
name='tournament', |
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='team_registrations', to='tournaments.tournament'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='teamscore', |
||||||
|
name='team_registration', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='team_scores', to='tournaments.teamregistration'), |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='tournament', |
||||||
|
name='event', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='tournaments', to='tournaments.event'), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,108 @@ |
|||||||
|
# Generated by Django 5.1 on 2024-11-15 14:45 |
||||||
|
|
||||||
|
import django.db.models.deletion |
||||||
|
import django.utils.timezone |
||||||
|
from django.conf import settings |
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('tournaments', '0097_club_last_updated_by_court_last_updated_by_and_more'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='club', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='court', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='dateinterval', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='devicetoken', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='event', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='failedapicall', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='groupstage', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='log', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='match', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='modellog', |
||||||
|
name='parent_model_id', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='modellog', |
||||||
|
name='parent_model_name', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='playerregistration', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='purchase', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='round', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='teamregistration', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='teamscore', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='tournament', |
||||||
|
name='last_updated_by', |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='dataaccess', |
||||||
|
name='creation_date', |
||||||
|
field=models.DateTimeField(default=django.utils.timezone.now, editable=False), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='dataaccess', |
||||||
|
name='last_update', |
||||||
|
field=models.DateTimeField(default=django.utils.timezone.now), |
||||||
|
), |
||||||
|
migrations.RemoveField( |
||||||
|
model_name='dataaccess', |
||||||
|
name='shared_with', |
||||||
|
), |
||||||
|
migrations.AlterField( |
||||||
|
model_name='tournament', |
||||||
|
name='event', |
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='tournaments.event'), |
||||||
|
), |
||||||
|
migrations.AddField( |
||||||
|
model_name='dataaccess', |
||||||
|
name='shared_with', |
||||||
|
field=models.ManyToManyField(related_name='shared_data', to=settings.AUTH_USER_MODEL), |
||||||
|
), |
||||||
|
] |
||||||
@ -0,0 +1,19 @@ |
|||||||
|
# Generated by Django 5.1 on 2024-11-18 12:54 |
||||||
|
|
||||||
|
import django.utils.timezone |
||||||
|
from django.db import migrations, models |
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration): |
||||||
|
|
||||||
|
dependencies = [ |
||||||
|
('tournaments', '0098_remove_club_last_updated_by_and_more'), |
||||||
|
] |
||||||
|
|
||||||
|
operations = [ |
||||||
|
migrations.AddField( |
||||||
|
model_name='dataaccess', |
||||||
|
name='last_hierarchy_update', |
||||||
|
field=models.DateTimeField(default=django.utils.timezone.now), |
||||||
|
), |
||||||
|
] |
||||||
Loading…
Reference in new issue