Adds sharable property to BaseModel classes

mailing
Laurent 2 months ago
parent 46001fc4e7
commit 09282698cf
  1. 54
      biz/admin.py
  2. 21
      sync/README.md
  3. 2
      sync/admin.py
  4. 15
      sync/models/base.py
  5. 2
      tournaments/admin.py
  6. 2
      tournaments/models/club.py

@ -429,57 +429,3 @@ class ActivityAdmin(SyncedObjectAdmin):
def get_event_display(self, obj):
return str(obj)
get_event_display.short_description = 'Activity'
# @admin.register(EmailCampaign)
# class EmailCampaignAdmin(admin.ModelAdmin):
# list_display = ('subject', 'event', 'sent_at')
# list_filter = ('sent_at',)
# search_fields = ('subject', 'content')
# date_hierarchy = 'sent_at'
# readonly_fields = ('sent_at',)
# @admin.register(EmailTracker)
# class EmailTrackerAdmin(admin.ModelAdmin):
# list_display = (
# 'campaign',
# 'prospect',
# 'tracking_id',
# 'sent_status',
# 'opened_status',
# 'clicked_status'
# )
# list_filter = ('sent', 'opened', 'clicked')
# search_fields = (
# 'prospect__name',
# 'prospect__email',
# 'campaign__subject'
# )
# readonly_fields = (
# 'tracking_id', 'sent', 'sent_at',
# 'opened', 'opened_at',
# 'clicked', 'clicked_at'
# )
# date_hierarchy = 'sent_at'
# def sent_status(self, obj):
# return self._get_status_html(obj.sent, obj.sent_at)
# sent_status.short_description = 'Sent'
# sent_status.allow_tags = True
# def opened_status(self, obj):
# return self._get_status_html(obj.opened, obj.opened_at)
# opened_status.short_description = 'Opened'
# opened_status.allow_tags = True
# def clicked_status(self, obj):
# return self._get_status_html(obj.clicked, obj.clicked_at)
# clicked_status.short_description = 'Clicked'
# clicked_status.allow_tags = True
# def _get_status_html(self, status, date):
# if status:
# return format_html(
# '<span style="color: green;">✓</span> {}',
# date.strftime('%Y-%m-%d %H:%M') if date else ''
# )
# return format_html('<span style="color: red;">✗</span>')

@ -0,0 +1,21 @@
### Synchronization quick ReadMe
- Data class must extend BaseModel
- Admin classes must extend SyncedObjectAdmin to have updates saved in the BaseModel properties
- The SynchronizationApi defines a get and a post service to POST new data, and GET updates. When performing an operation on a data, a ModelLog instance is created with the related information. When performing a GET, we retrieve the list of ModelLogs to sent the new data to the user.
- routing.py defines the URL of the websocket where messages are sent when updates are made. URL is by user.
### Sharing
- Data can be shared between users. To do that, a new DataAccess object can be created to define the owner, the authorized user, and the object id.
- By default, the whole hierarchy of objects are shared, from the data parents to all its children.
- Special data path can be specified for a class by defining a setting
example:
SYNC_MODEL_CHILDREN_SHARING = {
'Match': ['team_scores', 'team_registration', 'player_registrations']
}
Here when sharing a Match, we also share objects accessed through the names of the properties to get TeamScore, TeamRegistration and PlayerRegistration.
- It's also possible to exclude a class from being sharable by setting sharable = False in its definition. In PadelClub, Club is the top entity that links all data together, so we don't want the automatic data scanning to share clubs.

@ -5,7 +5,7 @@ from .models import BaseModel, ModelLog, DataAccess
class SyncedObjectAdmin(admin.ModelAdmin):
exclude = ('data_access_ids',)
# exclude = ('data_access_ids',)
raw_id_fields = ['related_user', 'last_updated_by']
def save_model(self, request, obj, form, change):

@ -16,6 +16,8 @@ class BaseModel(models.Model):
last_updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL, related_name='+')
data_access_ids = models.JSONField(default=list)
sharable = True
class Meta:
abstract = True
@ -39,6 +41,8 @@ class BaseModel(models.Model):
}
def update_data_access_list(self):
if self.sharable == False:
return
related_instances = self.sharing_related_instances()
data_access_ids = set()
for instance in related_instances:
@ -46,21 +50,18 @@ class BaseModel(models.Model):
data_access_ids.update(instance.data_access_ids)
# print(f'related_instances = {related_instances}')
# data_access_ids = [instance.data_access_ids for instance in related_instances if isinstance(instance, BaseModel)]
# data_access_ids.extend(self.data_access_ids)
self.data_access_ids = list(data_access_ids)
# DataAccess = apps.get_model('sync', 'DataAccess')
# data_accesses = DataAccess.objects.filter(model_id__in=related_ids)
# for data_access in data_accesses:
# self.add_data_access_relation(data_access)
def add_data_access_relation(self, data_access):
if self.sharable == False:
return
str_id = str(data_access.id)
if str_id not in self.data_access_ids:
self.data_access_ids.append(str_id)
def remove_data_access_relation(self, data_access):
if self.sharable == False:
return
try:
self.data_access_ids.remove(str(data_access.id))
except ValueError:

@ -95,7 +95,7 @@ class EventAdmin(SyncedObjectAdmin):
readonly_fields = ['display_images_preview']
fieldsets = [
(None, {'fields': ['last_update', 'related_user', 'name', 'club', 'creator', 'creation_date', 'tenup_id']}),
(None, {'fields': ['data_access_ids','last_update', 'related_user', 'name', 'club', 'creator', 'creation_date', 'tenup_id']}),
('Images', {'fields': ['display_images_preview'], 'classes': ['collapse']}),
]

@ -27,6 +27,8 @@ class Club(BaseModel):
broadcast_code = models.CharField(max_length=10, null=True, blank=True, unique=True)
admin_visible = models.BooleanField(default=False)
sharable = False
def delete_dependencies(self):
for court in self.courts.all():
# court.delete_dependencies()

Loading…
Cancel
Save