Skip to content

Commit 3603a9f

Browse files
authored
Merge pull request #56 from AyushDharDubey/fix/issue_54-add-delete-revision-feature
Adds `delete revision` option for admin
2 parents e81460a + e6a092b commit 3603a9f

File tree

5 files changed

+120
-14
lines changed

5 files changed

+120
-14
lines changed

mainapp/database.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -158,23 +158,23 @@ def edit(options):
158158

159159
return False
160160

161-
def delete(model_id):
161+
def delete(model_id, revision=None):
162162
try:
163163
with transaction.atomic():
164-
models = Model.objects.filter(model_id=model_id)
165-
changes = Change.objects.filter(model__model_id=model_id)
164+
if not revision:
165+
models = Model.objects.filter(model_id=model_id)
166+
else:
167+
models = Model.objects.filter(model_id=model_id, revision=revision)
166168

167169
if not models.exists():
168170
logger.exception(None, 'Model does not exist.')
169171
return False
170-
172+
171173
for m in models:
172-
path = '{}/{}'.format(settings.MODEL_DIR, m.model_id)
173-
if os.path.exists(path):
174-
shutil.rmtree(path)
175-
176-
changes.delete()
177-
models.delete()
174+
path = '{}/{}/{}.glb'.format(settings.MODEL_DIR, m.model_id, revision)
175+
if os.path.isfile(path):
176+
os.remove(path)
177+
m.delete()
178178

179179
logger.info('Model deleted successfully.')
180180
return True

mainapp/models.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,20 @@ def save(self, *args, **kwargs):
105105

106106
super().save(*args, **kwargs)
107107

108+
def delete(self, *args, **kwargs):
109+
with transaction.atomic():
110+
if self.latest:
111+
latest_model = Model.objects.filter(
112+
model_id=self.model_id
113+
).exclude(pk=self.pk).order_by('-revision').first()
114+
115+
# if self is not the last standing revision of the model
116+
# assign the next revision as latest
117+
if latest_model:
118+
latest_model.latest=True
119+
latest_model.save()
120+
return super().delete(*args, **kwargs)
121+
108122
class Change(models.Model):
109123
author = models.ForeignKey(User, models.CASCADE)
110124
model = models.ForeignKey(Model, models.CASCADE)

mainapp/templates/mainapp/model.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,12 @@ <h3 class="panel-title">{{ model.title }}</h3>
129129
<form action="{% url 'delete_model' %}" method="post" onsubmit="return confirmDeleteModel()">
130130
{% csrf_token %}
131131
<input type="hidden" name="model_id" value="{{ model.model_id }}">
132+
{% if not latest_page %}
133+
<input type="hidden" name="revision" value="{{ model.revision }}">
134+
<button type="submit" class="btn btn-danger">Delete Revision</button>
135+
{% else %}
132136
<button type="submit" class="btn btn-danger">Delete Model</button>
137+
{% endif %}
133138
</form>
134139
</p>
135140
{% endif %}

mainapp/tests/test_database.py

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,87 @@ def test_delete_model(self):
381381
Model.objects.get(pk=created_model.pk)
382382

383383
expected_path = os.path.join(
384-
settings.MODEL_DIR, str(created_model.model_id)
384+
settings.MODEL_DIR, str(created_model.model_id), str(created_model.revision)
385385
)
386386
self.assertFalse(os.path.exists(expected_path), "Model file should be deleted")
387387

388388
self.assertEqual(Change.objects.filter(model=created_model).count(), 0)
389+
390+
def test_delete_model_revision(self):
391+
model_file = self._create_dummy_file()
392+
options = {
393+
"title": "Model to Delete",
394+
"description": "This model will be deleted.",
395+
"tags": {"delete": "yes"},
396+
"categories": ["DeleteCat"],
397+
"latitude": 20.0,
398+
"longitude": 30.0,
399+
"source": None,
400+
"license": 8,
401+
"author": self.user,
402+
"translation": [0, 0, 0],
403+
"rotation": 0,
404+
"scale": 1,
405+
"revision": False,
406+
}
407+
408+
created_model = database.upload(model_file, options)
409+
self.assertIsNotNone(created_model)
410+
411+
revision_options = {
412+
"model_id": created_model.model_id,
413+
"author": self.user,
414+
"revision": True,
415+
}
416+
model_rev1 = database.upload(model_file, revision_options)
417+
self.assertIsNotNone(model_rev1)
418+
model_rev2 = database.upload(model_file, revision_options)
419+
self.assertIsNotNone(model_rev2)
420+
421+
delete_result = database.delete(model_rev2.model_id, model_rev2.revision)
422+
self.assertTrue(delete_result, "Delete should return True on success")
423+
424+
with self.assertRaises(Model.DoesNotExist):
425+
Model.objects.get(pk=model_rev2.pk)
426+
427+
expected_path = os.path.join(
428+
settings.MODEL_DIR, str(model_rev2.model_id), str(model_rev2.revision)
429+
)
430+
self.assertFalse(os.path.exists(expected_path), "Model file for revision 2 should be deleted")
431+
432+
self.assertEqual(Change.objects.filter(model=model_rev2).count(), 0)
433+
434+
model_rev1.refresh_from_db()
435+
self.assertTrue(model_rev1.latest)
436+
created_model.refresh_from_db()
437+
self.assertFalse(created_model.latest)
438+
439+
delete_result = database.delete(model_rev1.model_id, model_rev1.revision)
440+
self.assertTrue(delete_result, "Delete should return True on success")
441+
442+
with self.assertRaises(Model.DoesNotExist):
443+
Model.objects.get(pk=model_rev1.pk)
444+
445+
expected_path = os.path.join(
446+
settings.MODEL_DIR, str(model_rev1.model_id), str(model_rev1.revision)
447+
)
448+
self.assertFalse(os.path.exists(expected_path), "Model file for revision 1 should be deleted")
449+
450+
self.assertEqual(Change.objects.filter(model=model_rev1).count(), 0)
451+
452+
created_model.refresh_from_db()
453+
self.assertTrue(created_model.latest)
454+
455+
delete_result = database.delete(created_model.model_id, created_model.revision)
456+
self.assertTrue(delete_result, "Delete should return True on success")
457+
458+
with self.assertRaises(Model.DoesNotExist):
459+
Model.objects.get(pk=created_model.pk)
460+
461+
expected_path = os.path.join(
462+
settings.MODEL_DIR, str(created_model.model_id), str(created_model.revision)
463+
)
464+
self.assertFalse(os.path.exists(expected_path), "Model file for revision 1 should be deleted")
465+
466+
self.assertEqual(Change.objects.filter(model=created_model).count(), 0)
467+
self.assertEqual(Model.objects.filter(model_id=created_model.model_id).count(), 0)

mainapp/views.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def model(request, model_id, revision=None):
6464

6565
context = {
6666
'model': model,
67+
'latest_page': revision is None,
6768
'license': LICENSES_DISPLAY[model.license]
6869
}
6970

@@ -465,6 +466,7 @@ def delete_model(request):
465466
return redirect(index)
466467

467468
model_id = request.POST.get('model_id')
469+
revision = request.POST.get('revision')
468470

469471
if not model_id:
470472
return HttpResponseBadRequest('Model ID is required.')
@@ -473,10 +475,16 @@ def delete_model(request):
473475
messages.error(request, 'You must be admin to use this feature.')
474476
return redirect(model, model_id=model_id)
475477

476-
m = get_object_or_404(Model, model_id=model_id, latest=True)
478+
if not revision:
479+
m = get_object_or_404(Model, model_id=model_id, latest=True)
480+
else:
481+
m = get_object_or_404(Model, model_id=model_id, revision=revision)
477482

478-
if database.delete(m.model_id):
479-
messages.info(request, f'Model {m.title} deleted successfully.')
483+
if database.delete(model_id, revision):
484+
if revision:
485+
messages.info(request, f'Model {m.title} ({m.revision}) deleted successfully.')
486+
else:
487+
messages.info(request, f'Model {m.title} deleted successfully.')
480488
return redirect(index)
481489
else:
482490
messages.error(request, 'An error occurred while deleting the model. Please try again later.')

0 commit comments

Comments
 (0)