Кнопка действия администратора Django для каждой строки в ListView

#javascript #django #django-admin

#javascript #django #django-admin

Вопрос:

как в этом сообщении от hakibenita https://hakibenita.com/how-to-add-custom-action-buttons-to-django-admin , у меня была бы кнопка действия для каждой строки в admin listview. Эта кнопка должна изменить статус книги (просто поле символа с вариантами выбора в моделях), но я хочу, чтобы это делалось без открытия другой страницы, просто нажмите на кнопку, и статус будет изменен. Значение статуса выбирается из выбора, и нажатие кнопки действия вызывает javascript для чтения кнопки выбора, затем javascript вызывает страницу администратора для изменения статуса. Я не могу создать форму, потому что каждая строка в listview уже находится в форме. Я не хочу использовать действие администратора, потому что это действие для одного объекта.

Вот соответствующий код:

 admin.py:
class BookAdmin(admin.ModelAdmin): 
#...

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('changestatus/<str:status>/<int:bookid>', self.admin_site.admin_view(self.change_status), name = 'changestatus'),
            ]
        return custom_urls   urls


    def change_status(self, request, bookid=None, status=None):
        if bookid: 
            book = Book.objects.get(pk=bookid)
            if status == 'available':
                book.status = Book.AVAILABLE
            elif status == 'unavailable':
                book.status = Book.UNAVAILABLE
            book.save()
            
            newStatus = book.get_status_display()
            
            self.message_user(request, 'Changed status to "{}"'.format(newStatus), messages.SUCCESS)

        url = reverse(
            'admin:library_book_changelist',
            current_app=self.admin_site.name,
        )
        return HttpResponseRedirect(url)



   def status_button(self, obj):
            return format_html('{}<br />'
                            '<select id="selectstatus">'
                            '<option value="available-{}">Status available</option>'
                            '<option value="unavailable-{}">Status unavailable</option>'
                            '<button onclick="changestatus()">Change Status</button>',
                            obj.get_status_display(),
                            obj.pk,
                            obj.pk,
                            )
    status_button.short_description = 'Status'


#...


myjs.js:
function changestatus(){
    var val=document.getElementById("selectstatus").value;
    var valArr = val.split("-");
    var newstatus = valArr[0];
    var bookid = valArr[1];
    changestatusUrl = "/management/library/book/changestatus/" newstatus "/" bookid; 
//     window.open(changestatusUrl, '_self'); // works, changes status but don't display message
//     window.open(changestatusUrl,); // IT WORKS!! but opens another tab
    window.location.replace(changestatusUrl);  // works, changes status but don't display message
}
  

Большое спасибо

Комментарии:

1. Разве вы не можете просто сделать поле статуса и редактируемое поле в списке администраторов dajngo? docs.djangoproject.com/en/3.1/ref/contrib/admin /…

2. @LifeByBen это неплохая идея, но как контролировать разрешения на то, кто может использовать это поле?

3. Хороший вопрос — если его мелкие детали, такие как возможность просто обновить это одно поле или нет, я думаю, вы могли бы переопределить сохранение и там выполнить проверку разрешений на что-то подобное?

4. проверка в save() работает, но все видят выпадающий список выбора для изменения… я хочу, чтобы люди с правильными разрешениями видели только выпадающий список изменений