假设我有一个模型,其中ID为1的行是特殊的,不应该被删除,但所有其他行都可以删除。以下是我尝试实现该逻辑:
from django.db import models
class Widget(models.Model):
name = models.CharField(max_length=255)
class Meta:
ordering = ('name',)
def __unicode__(self):
return self.name
from django.contrib import admin
from .models import Widget
class WidgetAdmin(admin.ModelAdmin):
def has_delete_permission(self, request, obj=None):
return obj is None or obj.pk != 1
admin.site.register(Widget, WidgetAdmin)
上述代码会在obj.pk
为1
时从更改表单中删除“删除”按钮,这正是我想要的。但是,在更改列表中,如果我选中ID为1的行的复选框,然后使用“删除所选小部件”操作,我可以删除该行。我想阻止它,但仍然允许使用“删除所选小部件”操作删除所有其他行。我怎么能这样做?
答案 0 :(得分:11)
根据has_delete_permission
's docstring:
def has_delete_permission(self, request, obj=None):
"""
Returns True if the given request has permission to change the given
Django model instance, ...
"""
这意味着每个请求执行has_delete_permission
,而不是每个对象。在批量操作中,未设置obj
。但是,您可以检查request
:
def has_delete_permission(self, request, obj=None):
if request.POST and request.POST.get('action') == 'delete_selected':
return '1' not in request.POST.getlist('_selected_action')
return obj is None or obj.pk != 1
请注意,上述方法有效,因为the delete_selected
action takes has_delete_permission
into account。
您可能还想提供有关错误的一些详细信息:
from django.contrib import messages
def has_delete_permission(self, request, obj=None):
if request.POST and request.POST.get('action') == 'delete_selected':
if '1' in request.POST.getlist('_selected_action'):
messages.add_message(request, messages.ERROR, (
"Widget #1 is protected, please remove it from your selection "
"and try again."
))
return False
return True
return obj is None or obj.pk != 1
我猜每个请求调用has_delete_permission
而不是每个对象出于性能原因调用SELECT
。在一般情况下,在运行has_delete_permission
查询之前进行DELETE
查询并循环protected function getConfigFormValues()
{
return array(
'HREFLANGFORPRESTASHOP_MULTISHOP_LANGUAGE_MODE' => Configuration::get('HREFLANGFORPRESTASHOP_MULTISHOP_LANGUAGE_MODE')
);
}
(根据其工作可能会耗费时间)是没用的。如果与此相关,则由开发人员采取必要的步骤。
答案 1 :(得分:9)
您可以使用自己的delete_selected
操作取代管理员的from django.contrib.admin import actions
class WidgetAdmin(admin.ModelAdmin):
actions = [delete_selected]
def delete_selected(self, request, queryset):
# Handle this however you like. You could raise PermissionDenied,
# or just remove it, and / or use the messages framework...
queryset = queryset.exclude(pk=1)
actions.delete_selected(self, request, queryset)
delete_selected.short_description = "Delete stuff"
操作实施。类似的东西:
(function() {
angular.module('WizmoApp').controller('StoreController', storeController);
storeController.$inject = ['$scope', '$http', '$q', '$window', 'MyService', 'toastr'];
function storeController($scope, $http, $q, $window, MyService, toastr) {
StoreService.getStores().then(
function(response) {
console.log(response);
},
function(response) {
toastr.error(response);
});
}
})();
有关详细信息,请参阅the documentation。