django:通用删除视图

0 投票
1 回答
1579 浏览
提问于 2025-04-18 16:21

我想为我的应用程序建立一个通用的删除视图。基本上,我希望它的行为和标准的Django后台管理系统一样。比如,我想用同一个视图(和模板)来删除不同的对象。

我在查阅Django文档时发现,DeleteViews通常是和它们要删除的模型绑定在一起的。比如:

class AuthorDelete(DeleteView):
    model = Author
    success_url = reverse_lazy('author-list')

而我想创建一些更通用的东西,比如:

class AnyDelete(DeleteView):
    model = I want to have a list of models here
    success_url = reverse_lazy('some-remaining-list')

1 个回答

1

创建基于类的视图(CBVs)的原因就是为了帮助解决像你这样的问题。正如你已经提到的,要创建自己的删除视图,你只需要继承 DeleteView 类,并修改两个属性。我觉得这非常简单,我经常这么做(唯一需要手动操作的就是把它连接到 urls.py 文件中)。

不过,如果你真的想创建一个更通用的视图(比如说一个视图可以删除任何类型的模型),那么你需要使用 内容类型框架。在文档中你会看到,内容类型框架可以用来处理任意模型的对象。所以,在你的情况下,你可以创建一个简单的视图,它会接收三个参数:app_label、模型和要删除的模型的主键(pk)。然后你可以这样实现:

from django.contrib.contenttypes.models import ContentType
from django.shortcuts import get_object_or_404

def generic_delete_view(request, app_label, pk):
  if request.method == 'POST':
    my_type = ContentType.objects.get(app_label=app_label, model=model)
    get_object_or_404(my_type.model_class(), pk=pk).delete()

    # here you must determine *where* to return to
    # probably by adding a class method to your Models 

当然,在你的 urls.py 文件中,你需要把这个视图连接起来,以便它能接收这三个参数(然后像这样调用它 /generic_delete/application/Model/3)。下面是一个如何在 urls.py 中连接它的例子:

urlpatterns = patterns('',
  # ....
  url(
    r'^generic_delete/(?P<app_label>\w+)/(?P<model>\w+)/(?P<pk>\d+)$',
    views.generic_delete_view,  
    name='generic_delete' 
  ) ,
  # ...
)

如果你有一个对象列表,并想获取每个对象的 app_label 和模型,以便构建通用删除的 URL,你可以这样做:

from django.core.urlresolvers import reverse

object = # ... 
ct = ContentType.objects.get_for_model(object)
generic_delete_url = reverse('generic_delete', kwargs = {
  app_label=ct.app_label,
  model=ct.model,
  pk=object.pk
})
# so generic_delete_url now will be something like /my_app/MyModel/42

撰写回答