Browse Source

Add support for soft delete for data. Models are not deleted, but marked as deleted.

V1
Joshua Rubingh 2 years ago
parent
commit
7b85bb2223
  1. 4
      VRE/VRE/settings.py
  2. 5
      VRE/apps/api/admin.py
  3. 18
      VRE/apps/api/migrations/0002_token_deleted.py
  4. 7
      VRE/apps/dropoff/admin.py
  5. 18
      VRE/apps/dropoff/migrations/0002_datadrop_deleted.py
  6. 5
      VRE/apps/invitation/admin.py
  7. 18
      VRE/apps/invitation/migrations/0002_invitation_deleted.py
  8. 8
      VRE/apps/researcher/admin.py
  9. 18
      VRE/apps/researcher/migrations/0002_researcher_deleted.py
  10. 9
      VRE/apps/storage/admin.py
  11. 23
      VRE/apps/storage/migrations/0003_auto_20210413_0813.py
  12. 5
      VRE/apps/study/admin.py
  13. 18
      VRE/apps/study/migrations/0002_study_deleted.py
  14. 2
      VRE/apps/study/models.py
  15. 14
      VRE/apps/virtual_machine/admin.py
  16. 53
      VRE/apps/virtual_machine/migrations/0002_auto_20210413_0813.py
  17. 9
      VRE/apps/vrw/admin.py
  18. 45
      VRE/apps/vrw/migrations/0002_auto_20210413_0813.py
  19. 1
      VRE/apps/vrw/models.py
  20. 4
      VRE/lib/models/base.py
  21. 3
      VRE/requirements.txt
  22. 10
      VRE/templates/admin/base_site.html

4
VRE/VRE/settings.py

@ -40,6 +40,8 @@ INSTALLED_APPS = [ @@ -40,6 +40,8 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'safedelete',
'apps.api',
'apps.dropoff',
'apps.invitation',
@ -74,7 +76,7 @@ ROOT_URLCONF = 'VRE.urls' @@ -74,7 +76,7 @@ ROOT_URLCONF = 'VRE.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [f'{BASE_DIR / "templates"}'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [

5
VRE/apps/api/admin.py

@ -1,9 +1,10 @@ @@ -1,9 +1,10 @@
from django.contrib import admin
from safedelete.admin import SafeDeleteAdmin
from .models import Token
@admin.register(Token)
class TokenAdmin(admin.ModelAdmin):
list_display = ('key', 'user','is_supertoken', 'last_access')
class TokenAdmin(SafeDeleteAdmin):
list_display = ('key', 'user','is_supertoken', 'last_access') + SafeDeleteAdmin.list_display
ordering = ('-last_access', 'user', )
search_fields = ('key', 'user__username',)
readonly_fields = ('created_at', 'updated_at')

18
VRE/apps/api/migrations/0002_token_deleted.py

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-04-13 08:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='token',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
]

7
VRE/apps/dropoff/admin.py

@ -1,12 +1,13 @@ @@ -1,12 +1,13 @@
from django.contrib import admin
from safedelete.admin import SafeDeleteAdmin
from django.template.defaultfilters import filesizeformat
from .models import DataDrop
# Register your models here.
@admin.register(DataDrop)
class DataDropAdmin(admin.ModelAdmin):
list_display = ('original_filename', '_filesize', 'created_at', 'study','uploader')
class DataDropAdmin(SafeDeleteAdmin):
list_display = ('original_filename', '_filesize', 'created_at', 'study','uploader') + SafeDeleteAdmin.list_display
ordering = ('-created_at', 'original_filename', )
search_fields = ('original_filename', 'study__name',)
readonly_fields = ('study','original_filename','upload_filename','filepath','uploader','_filesize','ip','created_at',)
@ -14,6 +15,6 @@ class DataDropAdmin(admin.ModelAdmin): @@ -14,6 +15,6 @@ class DataDropAdmin(admin.ModelAdmin):
def _filesize(self,obj):
return filesizeformat(0 if obj.pk is None else obj.filesize)
# This will help you to disbale add functionality. It is not possible to upload files through the admin.
# This will help you to disable add functionality. It is not possible to upload files through the admin.
def has_add_permission(self, request):
return False

18
VRE/apps/dropoff/migrations/0002_datadrop_deleted.py

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-04-13 08:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('dropoff', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='datadrop',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
]

5
VRE/apps/invitation/admin.py

@ -1,9 +1,10 @@ @@ -1,9 +1,10 @@
from django.contrib import admin
from safedelete.admin import SafeDeleteAdmin
from .models import Invitation
@admin.register(Invitation)
class InvitationAdmin(admin.ModelAdmin):
list_display = ('name', 'email', 'study','researcher', 'upload_code', 'created_at')
class InvitationAdmin(SafeDeleteAdmin):
list_display = ('name', 'email', 'study','researcher', 'upload_code', 'created_at') + SafeDeleteAdmin.list_display
ordering = ('-created_at', 'name', 'email', )
search_fields = ('name', 'email','study__name')
readonly_fields = ('mail_sent', 'created_at', 'updated_at')

18
VRE/apps/invitation/migrations/0002_invitation_deleted.py

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-04-13 08:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('invitation', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='invitation',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
]

8
VRE/apps/researcher/admin.py

@ -1,4 +1,10 @@ @@ -1,4 +1,10 @@
from django.contrib import admin
from safedelete.admin import SafeDeleteAdmin
from .models import Researcher
admin.site.register(Researcher)
@admin.register(Researcher)
class ResearcherAdmin(SafeDeleteAdmin):
list_display = ('user',) + SafeDeleteAdmin.list_display
ordering = ('user', )
search_fields = ('user__username',)
readonly_fields = ('created_at', 'updated_at')

18
VRE/apps/researcher/migrations/0002_researcher_deleted.py

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-04-13 08:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('researcher', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='researcher',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
]

9
VRE/apps/storage/admin.py

@ -1,16 +1,17 @@ @@ -1,16 +1,17 @@
from django.contrib import admin
from safedelete.admin import SafeDeleteAdmin
from .models import StorageEngine, StorageLocation
@admin.register(StorageEngine)
class StorageEngineAdmin(admin.ModelAdmin):
list_display = ('name', 'engine', 'researcher', 'created_at')
class StorageEngineAdmin(SafeDeleteAdmin):
list_display = ('name', 'engine', 'researcher', 'created_at') + SafeDeleteAdmin.list_display
ordering = ('-created_at', 'name', )
search_fields = ('name', 'engine', 'researcher')
readonly_fields = ('created_at', 'updated_at')
@admin.register(StorageLocation)
class StorageLocationAdmin(admin.ModelAdmin):
list_display = ( 'study', 'researcher', 'storageengine', 'encrypted', 'created_at')
class StorageLocationAdmin(SafeDeleteAdmin):
list_display = ( 'study', 'researcher', 'storageengine', 'encrypted', 'created_at') + SafeDeleteAdmin.list_display
ordering = ('-created_at', 'study__name', )
search_fields = ( 'study', 'researcher', 'storageengine')
readonly_fields = ('created_at', 'updated_at')

23
VRE/apps/storage/migrations/0003_auto_20210413_0813.py

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
# Generated by Django 3.1.7 on 2021-04-13 08:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('storage', '0002_storagelocation_uploadpath'),
]
operations = [
migrations.AddField(
model_name='storageengine',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
migrations.AddField(
model_name='storagelocation',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
]

5
VRE/apps/study/admin.py

@ -1,12 +1,13 @@ @@ -1,12 +1,13 @@
from django.contrib import admin
from safedelete.admin import SafeDeleteAdmin
from django.template.defaultfilters import filesizeformat
from .models import Study
# Register your models here.
@admin.register(Study)
class StudyAdmin(admin.ModelAdmin):
list_display = ('name', 'researcher', 'total_files', 'total_file_size', 'total_invitations', 'created_at')
class StudyAdmin(SafeDeleteAdmin):
list_display = ('name', 'researcher', 'total_files', 'total_file_size', 'total_invitations', 'created_at') + SafeDeleteAdmin.list_display
ordering = ('-created_at','name', 'researcher')
search_fields = ('name', 'researcher')
readonly_fields = ('upload_uuid', 'api_upload_url', 'total_files', 'total_file_size', 'total_invitations', 'created_at', 'updated_at')

18
VRE/apps/study/migrations/0002_study_deleted.py

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-04-13 08:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('study', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='study',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
]

2
VRE/apps/study/models.py

@ -60,6 +60,7 @@ class Study(MetaDataModel): @@ -60,6 +60,7 @@ class Study(MetaDataModel):
verbose_name_plural = _('studies')
ordering = ['name']
researcher = models.ForeignKey(Researcher, verbose_name=Researcher._meta.verbose_name, on_delete=models.CASCADE, help_text=_('Choose the researcher which owns this study'))
name = models.CharField(_('Name'), max_length=200, help_text=_('Name of the research study.'))
description = models.TextField(_('Description'), blank=True, null=True, help_text=_('Enter a short description for this study.'))
@ -79,6 +80,7 @@ class Study(MetaDataModel): @@ -79,6 +80,7 @@ class Study(MetaDataModel):
@property
def get_absolute_url(self):
"""str: Returns the full url to the study detail page."""
#return 'aaa'
return reverse('study:detail', kwargs={'study_id': self.pk})
@property

14
VRE/apps/virtual_machine/admin.py

@ -1,4 +1,6 @@ @@ -1,4 +1,6 @@
from django.contrib import admin
from safedelete.admin import SafeDeleteAdmin
from django.template.defaultfilters import filesizeformat
from .models import (VirtualMachineOperatingSystem,
@ -12,8 +14,8 @@ from .models import (VirtualMachineOperatingSystem, @@ -12,8 +14,8 @@ from .models import (VirtualMachineOperatingSystem,
# Register your models here.
@admin.register(VirtualMachine)
class VirtualMachineAdmin(admin.ModelAdmin):
list_display = ('name', 'researcher', 'total_memory', 'total_storage', 'created_at')
class VirtualMachineAdmin(SafeDeleteAdmin):
list_display = ('name', 'researcher', 'total_memory', 'total_storage', 'created_at') + SafeDeleteAdmin.list_display
search_fields = ('name', 'researcher')
ordering = ('-created_at', 'name', 'researcher', )
readonly_fields = ('created_at', 'updated_at')
@ -24,8 +26,8 @@ class VirtualMachineAdmin(admin.ModelAdmin): @@ -24,8 +26,8 @@ class VirtualMachineAdmin(admin.ModelAdmin):
def total_storage(self, obj):
return filesizeformat(obj.total_storage)
class VirtualMachinePartAdmin(admin.ModelAdmin):
list_display = ('name', 'is_available', 'created_at')
class VirtualMachinePartAdmin(SafeDeleteAdmin):
list_display = ('name', 'is_available', 'created_at') + SafeDeleteAdmin.list_display
search_fields = ('name', )
ordering = ('-created_at', 'name', )
readonly_fields = ('created_at', 'updated_at')
@ -56,8 +58,8 @@ class VirtualMachineProfileAdmin(VirtualMachinePartAdmin): @@ -56,8 +58,8 @@ class VirtualMachineProfileAdmin(VirtualMachinePartAdmin):
pass
@admin.register(VirtualMachineAccess)
class VirtualMachineAccessAdmin(admin.ModelAdmin):
list_display = ('researcher', 'virtual_machine', 'created_at')
class VirtualMachineAccessAdmin(SafeDeleteAdmin):
list_display = ('researcher', 'virtual_machine', 'created_at') + SafeDeleteAdmin.list_display
search_fields = ('researcher', 'virtual_machine')
ordering = ('-created_at', 'researcher', )
readonly_fields = ('user','created_at', 'updated_at')

53
VRE/apps/virtual_machine/migrations/0002_auto_20210413_0813.py

@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
# Generated by Django 3.1.7 on 2021-04-13 08:13
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('virtual_machine', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='virtualmachine',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
migrations.AddField(
model_name='virtualmachineaccess',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
migrations.AddField(
model_name='virtualmachinegpu',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
migrations.AddField(
model_name='virtualmachinememory',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
migrations.AddField(
model_name='virtualmachinenetwork',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
migrations.AddField(
model_name='virtualmachineoperatingsystem',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
migrations.AddField(
model_name='virtualmachineprofile',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
migrations.AddField(
model_name='virtualmachinestorage',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
]

9
VRE/apps/vrw/admin.py

@ -1,12 +1,13 @@ @@ -1,12 +1,13 @@
from django.contrib import admin
from safedelete.admin import SafeDeleteAdmin
from .models import WorkspacePart, Workspace
from lib.models.admin import VRWRelatedSelectWidget
# Register your models here.
@admin.register(WorkspacePart)
class VRWPartAdmin(admin.ModelAdmin):
list_display = ('name', 'created_at')
class VRWPartAdmin(SafeDeleteAdmin):
list_display = ('name', 'created_at') + SafeDeleteAdmin.list_display
search_fields = ('name', )
ordering = ('-created_at', 'name', )
readonly_fields = ('created_at', 'updated_at')
@ -17,7 +18,7 @@ class VRWPartAdmin(admin.ModelAdmin): @@ -17,7 +18,7 @@ class VRWPartAdmin(admin.ModelAdmin):
return super(VRWPartAdmin, self).formfield_for_dbfield(db_field,**kwargs)
@admin.register(Workspace)
class VRWWorkspaceAdmin(admin.ModelAdmin):
list_display = ('virtual_machine', 'created_at')
class VRWWorkspaceAdmin(SafeDeleteAdmin):
list_display = ('virtual_machine', 'created_at') + SafeDeleteAdmin.list_display
ordering = ('-created_at', )
readonly_fields = ('created_at', 'updated_at')

45
VRE/apps/vrw/migrations/0002_auto_20210413_0813.py

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
# Generated by Django 3.1.7 on 2021-04-13 08:13
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('vrw', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='workspace',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
migrations.AddField(
model_name='workspacepart',
name='deleted',
field=models.DateTimeField(editable=False, null=True),
),
migrations.AlterField(
model_name='workspace',
name='ending_at',
field=models.DateTimeField(help_text='Enter the end date when this workspace should be terminated', verbose_name='Ending at'),
),
migrations.AlterField(
model_name='workspace',
name='starting_at',
field=models.DateTimeField(help_text='Enter the start date when this workspace should be created', verbose_name='Starting at'),
),
migrations.AlterField(
model_name='workspacepart',
name='content_type',
field=models.ForeignKey(help_text='Select the Virtual Machine part that correspondents with this workspace part.', limit_choices_to={'app_label': 'virtual_machine'}, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype'),
),
migrations.AlterField(
model_name='workspacepart',
name='name',
field=models.CharField(help_text='Human readable name for this workspace part.', max_length=100, verbose_name='Name'),
),
]

1
VRE/apps/vrw/models.py

@ -26,6 +26,7 @@ class WorkspacePart(MetaDataModel, CloudBasicDataModel): @@ -26,6 +26,7 @@ class WorkspacePart(MetaDataModel, CloudBasicDataModel):
object_id : int
Specify the virtual machine part id
"""
name = models.CharField(_('Name'), max_length=100, help_text=_('Human readable name for this workspace part.'))
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, limit_choices_to={'app_label': 'virtual_machine'}, help_text=_('Select the Virtual Machine part that correspondents with this workspace part.'))

4
VRE/lib/models/base.py

@ -2,7 +2,9 @@ @@ -2,7 +2,9 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
class MetaDataModel(models.Model):
from safedelete.models import SafeDeleteModel
class MetaDataModel(SafeDeleteModel):
"""
This is an abstract Django model with some general meta fields that can be used for other models.

3
VRE/requirements.txt

@ -22,4 +22,5 @@ giteapy==1.0.8 @@ -22,4 +22,5 @@ giteapy==1.0.8
requests==2.25.1
requests-hawk==1.1.0
PyGithub==1.54.1
python-irodsclient==0.8.6
python-irodsclient==0.8.6
django-safedelete==1.0.0

10
VRE/templates/admin/base_site.html

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
{% extends "admin/base_site.html" %}
{% block footer %}
<div id="footer"></div>
<script>
// Show soft deleted items. This works nicer then the original safedelete HTML/CSS
window.django.jQuery(function(){
window.django.jQuery('td.field-deleted').not(':contains(-)').parent('tr').addClass('deleted');
});
</script>
{% endblock %}
Loading…
Cancel
Save