diff --git a/forum/admin.py b/forum/admin.py index fa2b6e7f7..7dab61578 100644 --- a/forum/admin.py +++ b/forum/admin.py @@ -18,13 +18,16 @@ # See AUTHORS file. # +from adminsortable.admin import SortableAdmin from django.contrib import admin -from forum.models import Forum, Thread, Post + +from forum.models import Forum, Post, Thread + @admin.register(Forum) -class ForumAdmin(admin.ModelAdmin): +class ForumAdmin(SortableAdmin): raw_id_fields = ('last_post', ) - list_display = ('name', 'num_threads', 'change_order') + list_display = ('name', 'num_threads') @@ -42,4 +45,3 @@ class PostAdmin(admin.ModelAdmin): raw_id_fields = ('author', 'thread') list_display = ('thread', 'author', 'created') search_fields = ('=author__username', "body") - diff --git a/forum/migrations/0004_alter_forum_order.py b/forum/migrations/0004_alter_forum_order.py new file mode 100644 index 000000000..c56f63cf7 --- /dev/null +++ b/forum/migrations/0004_alter_forum_order.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.17 on 2023-09-27 19:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('forum', '0003_auto_20230201_1102'), + ] + + operations = [ + migrations.AlterField( + model_name='forum', + name='order', + field=models.PositiveIntegerField(default=0, editable=False), + ), + ] diff --git a/freesound/settings.py b/freesound/settings.py index 9c6a8f044..acf0b93dc 100644 --- a/freesound/settings.py +++ b/freesound/settings.py @@ -79,6 +79,7 @@ 'silk', 'admin_reorder', 'captcha', + 'adminsortable', ] # Specify custom ordering of models in Django Admin index diff --git a/freesound/urls.py b/freesound/urls.py index 4f5f24130..9e875cfa9 100644 --- a/freesound/urls.py +++ b/freesound/urls.py @@ -33,7 +33,6 @@ import comments.views import bookmarks.views import follow.views -import general.views import donations.views import utils.tagrecommendation_utilities as tagrec from apiv2.apiv2_utils import apiv1_end_of_life_message @@ -123,8 +122,6 @@ re_path(r'^crossdomain\.xml$', TemplateView.as_view(template_name='crossdomain.xml'), name="crossdomain"), # admin views - re_path(r'^admin/orderedmove/(?Pup|down)/(?P\d+)/(?P\d+)/$', - general.views.admin_move_ordered_model, name="admin-move"), path('admin/doc/', include('django.contrib.admindocs.urls')), path('admin/', admin.site.urls), diff --git a/general/models.py b/general/models.py index 25dfeb49d..e8c6e0f74 100644 --- a/general/models.py +++ b/general/models.py @@ -17,17 +17,15 @@ # Authors: # See AUTHORS file. # - -from comments.models import Comment +from adminsortable.models import SortableMixin from django.contrib.auth.models import User from django.contrib.contenttypes import fields -from django.contrib.contenttypes.models import ContentType -from django.urls import reverse from django.db import models + from favorites.models import Favorite -from ratings.models import SoundRating from tags.models import TaggedItem + class SocialModel(models.Model): tags = fields.GenericRelation(TaggedItem) fans = fields.GenericRelation(Favorite) @@ -40,48 +38,8 @@ class AkismetSpam(SocialModel): spam = models.TextField() created = models.DateTimeField(auto_now_add=True) -class OrderedModel(models.Model): - order = models.PositiveIntegerField(editable=False) - - def save(self, *args, **kwargs): - if not self.id: - try: - self.order = self.__class__.objects.all().order_by("-order")[0].order + 1 - except IndexError: - self.order = 0 - super().save(*args, **kwargs) - - def change_order(self): - model_type_id = ContentType.objects.get_for_model(self.__class__).id - model_id = self.id - kwargs = {"direction": "up", "model_type_id": model_type_id, "model_id": model_id} - url_up = reverse("admin-move", kwargs=kwargs) - kwargs["direction"] = "down" - url_down = reverse("admin-move", kwargs=kwargs) - return mark_safe(f'up | down') - change_order.short_description = 'Move' - change_order.admin_order_field = 'order' - - @staticmethod - def move(direction, model_type_id, model_id): - try: - ModelClass = ContentType.objects.get(id=model_type_id).model_class() - - current_model = ModelClass.objects.get(id=model_id) - - if direction == "down": - swap_model = ModelClass.objects.filter(order__gt=current_model.order).order_by("order")[0] - elif direction == "up": - swap_model = ModelClass.objects.filter(order__lt=current_model.order).order_by("-order")[0] - - current_model.order, swap_model.order = swap_model.order, current_model.order - - current_model.save() - swap_model.save() - except IndexError: - pass - except ModelClass.DoesNotExist: - pass +class OrderedModel(SortableMixin): + order = models.PositiveIntegerField(default=0, editable=False) class Meta: ordering = ["order"] diff --git a/general/views.py b/general/views.py deleted file mode 100644 index a8d5d650e..000000000 --- a/general/views.py +++ /dev/null @@ -1,39 +0,0 @@ -# -# Freesound is (c) MUSIC TECHNOLOGY GROUP, UNIVERSITAT POMPEU FABRA -# -# Freesound is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# Freesound is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -# Authors: -# See AUTHORS file. -# - -from django.contrib.admin.views.decorators import staff_member_required -from django.contrib.contenttypes.models import ContentType -from django.http import HttpResponseRedirect -from general.models import OrderedModel -from django.db import transaction - -@staff_member_required -@transaction.atomic() -def admin_move_ordered_model(request, direction, model_type_id, model_id): - OrderedModel.move(direction, model_type_id, model_id) - - ModelClass = ContentType.objects.get(id=model_type_id).model_class() - - app_label = ModelClass._meta.app_label - model_name = ModelClass.__name__.lower() - - url = f"/admin/{app_label}/{model_name}/" - - return HttpResponseRedirect(url) diff --git a/requirements.in b/requirements.in index 932e891fe..57bb8a852 100644 --- a/requirements.in +++ b/requirements.in @@ -6,6 +6,7 @@ boto3==1.26.130 celery==4.4.7 debugpy==1.5.1 dj-database-url==0.5.0 +django-admin-sortable==2.2.4 django-amazon-ses==4.0.1 django-cors-headers==3.13.0 django-debug-toolbar==3.1.1 diff --git a/requirements.txt b/requirements.txt index 60f3ebb3a..557fb9e7f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,6 +10,8 @@ alabaster==0.7.13 # via sphinx amqp==2.6.1 # via kombu +appnope==0.1.3 + # via ipython asgiref==3.7.2 # via django asttokens==2.2.1 @@ -76,6 +78,7 @@ dj-database-url==0.5.0 django==3.2.17 # via # -r requirements.in + # django-admin-sortable # django-amazon-ses # django-cors-headers # django-debug-toolbar @@ -87,6 +90,8 @@ django==3.2.17 # django-redis # django-silk # djangorestframework +django-admin-sortable==2.2.4 + # via -r requirements.in django-amazon-ses==4.0.1 # via -r requirements.in django-cors-headers==3.13.0 diff --git a/sounds/migrations/0050_alter_license_order.py b/sounds/migrations/0050_alter_license_order.py new file mode 100644 index 000000000..0616ead44 --- /dev/null +++ b/sounds/migrations/0050_alter_license_order.py @@ -0,0 +1,18 @@ +# Generated by Django 3.2.17 on 2023-09-27 19:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sounds', '0049_license_summary_for_describe_form'), + ] + + operations = [ + migrations.AlterField( + model_name='license', + name='order', + field=models.PositiveIntegerField(default=0, editable=False), + ), + ]