Fakultas Ilmu Komputer UI

Commit a3591023 authored by Rizkhi PH's avatar Rizkhi PH 🤔
Browse files

[#35] Material: Delete Material (Soft Delete/Recycle Bin)

parent d5c0345b
......@@ -30,6 +30,7 @@
<th scope="col">Kontributor</th>
<th scope="col">Status</th>
<th scope="col">Jumlah Like</th>
<th scope="col">Pilihan</th>
</tr>
</thead>
<tfoot>
......@@ -40,6 +41,7 @@
<th scope="col">Kontributor</th>
<th scope="col">Status</th>
<th scope="col">Jumlah Like</th>
<th scope="col">Pilihan</th>
</tr>
</tr>
</tfoot>
......@@ -57,6 +59,11 @@
<td>{{ materi.uploader }}</td>
<td>{{ materi.status }}</td>
<td>{{ materi.like_count }}</td>
<td>
{% if not materi.deleted_at %}<a type="button" href="/materi/{{materi.id}}/delete" class="reject-button button-decoration"
style="background-color:red">Hapus</a>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
......
......@@ -505,7 +505,7 @@ class KelolaMateriView(TemplateView):
def get_context_data(self, **kwargs):
context = super(KelolaMateriView, self).get_context_data(**kwargs)
context['materi_list'] = Materi.objects.all()
context['materi_list'] = Materi.all_objects.all()
return context
def get(self, request, *args, **kwargs):
......
# Generated by Django 3.1 on 2020-10-23 03:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0022_merge_20201011_1122'),
]
operations = [
migrations.AddField(
model_name='materi',
name='deleted_at',
field=models.DateTimeField(blank=True, null=True),
),
]
......@@ -39,6 +39,15 @@ class Category(models.Model):
class MateriManager(models.Manager):
def __init__(self, *args, **kwargs):
self.alive_only = kwargs.pop('alive_only', True)
super(MateriManager, self).__init__(*args, **kwargs)
def get_queryset(self):
if self.alive_only:
return SoftDeletionQuerySet(self.model).filter(deleted_at=None)
return SoftDeletionQuerySet(self.model)
def search(self, search_text):
search_vector = search.SearchVector("title", weight="A")
search_query = search.SearchQuery(search_text)
......@@ -51,8 +60,23 @@ class MateriManager(models.Manager):
return search_result
class SoftDeletionQuerySet(models.query.QuerySet):
def delete(self):
return super(SoftDeletionQuerySet, self).update(deleted_at=timezone.now())
class Materi(models.Model):
class SoftDeleteModel(models.Model):
deleted_at = models.DateTimeField(blank=True, null=True)
all_objects = MateriManager(alive_only=False)
class Meta:
abstract = True
def soft_delete(self):
self.deleted_at = timezone.now()
self.save()
class Materi(SoftDeleteModel):
cover = models.ImageField()
content = models.FileField()
title = models.CharField(max_length=50, default="Judul")
......@@ -61,7 +85,7 @@ class Materi(models.Model):
publisher = models.CharField(max_length=30, default="Penerbit")
release_year = models.IntegerField(default=current_year)
pages = models.IntegerField(default=0)
descriptions = models.TextField(default="Deskripsi")
descriptions = models.TextField(default="Deskripsi")
status = models.CharField(max_length=30, choices=VERIFICATION_STATUS, default=VERIFICATION_STATUS[0][0])
categories = models.ManyToManyField(Category)
date_created = models.DateTimeField(default=timezone.now)
......
......@@ -1071,26 +1071,57 @@ class DashboardKontributorViewTest(TestCase):
html = response.content.decode("utf-8")
self.assertIn(ERROR_403_MESSAGE, html)
class DeleteMateriTest(TestCase):
def setUp(self):
self.client = Client()
self.admin_credential = {
"email": "admin@gov.id",
"password": id_generator()
}
self.superuser_credential = {
"email": "superuser@gov.id",
"password": id_generator()
}
self.contributor_credential = {
"email": "contributor@gov.id",
"password": id_generator()
}
self.admin = get_user_model().objects.create_user(
**self.admin_credential, name="Admin", is_admin=True)
self.superuser = get_user_model().objects.create_user(
**self.superuser_credential, name="Superuser", is_admin=True, is_superuser=True)
self.content = SimpleUploadedFile(
"content.txt", b"Test")
self.cover = SimpleUploadedFile(
"flower.jpg", b"Test file")
self.contributor = User.objects.create_contributor(email="kontributor@gov.id",
password="kontributor")
self.contributor = User.objects.create_contributor(**self.contributor_credential)
Materi(title="Materi 1", author="Agas", uploader=self.contributor,
publisher="Kelas SC", descriptions="Deskripsi Materi 1",
status="APPROVE", cover=self.cover, content=self.content).save()
self.materi1 = Materi.objects.first()
self.url = "/materi/" + str(self.materi1.id) + "/delete"
def test_url_delete_materi_is_success(self):
def test_url_delete_materi_is_success_as_contributor(self):
self.client.login(**self.contributor_credential)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 302)
def test_url_soft_delete_materi_is_success_as_admin(self):
self.client.login(**self.admin_credential)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 302)
self.materi1.refresh_from_db()
self.assertNotEqual(self.materi1.deleted_at, None)
def test_url_soft_delete_materi_is_success_as_superuser(self):
self.client.login(**self.superuser_credential)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 302)
self.materi1.refresh_from_db()
self.assertNotEqual(self.materi1.deleted_at, None)
class ProfilViewTest(TestCase):
@classmethod
def setUpTestData(cls):
......
......@@ -259,6 +259,9 @@ def view_materi(request, pk):
def delete_materi(request, pk):
materi = get_object_or_404(Materi, pk=pk)
if request.user.is_superuser or request.user.is_admin:
materi.soft_delete()
return HttpResponseRedirect("/administration/")
materi.delete()
return HttpResponseRedirect("/dashboard/")
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment