基于Django类的DeleteView示例
有谁知道或任何人都可以请产生一个简单的例子,Django的基于类的genericsDeleteView? 我想要子类DeleteView,并确保当前login的用户拥有对象之前,它被删除。 任何帮助将非常感激。 先谢谢你。
这是一个简单的:
from django.views.generic import DeleteView from django.http import Http404 class MyDeleteView(DeleteView): def get_object(self, queryset=None): """ Hook to ensure object is owned by request.user. """ obj = super(MyDeleteView, self).get_object() if not obj.owner == self.request.user: raise Http404 return obj
注意事项:
-
DeleteView
不会删除GET
请求; 这是您提供确认模板的机会(您可以在template_name
类属性中提供名称),并带有一个“Yes I'm sure”button - 你可能更喜欢404错误信息? 在这种情况下,请改为使用
delete
方法,在get_object
调用之后检查权限并返回自定义的响应。 - 不要忘了提供一个匹配(可select定制的)
success_url
类属性的模板,以便用户可以确认该对象已被删除。
我已经基本分类了一些基于类的基础视图来做到这一点。 主要的区别是我只是筛选出了查询集。 我不能保证这种方法是好还是坏,但对我来说更有意义。
随意忽略“MessageMixin” – 这只是在那里用Django消息框架w /为每个视图指定的variables轻松呈现消息。 以下是我为我们的网站编写的代码:
查看
from django.views.generic import CreateView, UpdateView, \ DeleteView, ListView, DetailView from myproject.core.views import MessageMixin class RequestCreateView(MessageMixin, CreateView): """ Sub-class of the CreateView to automatically pass the Request to the Form. """ success_message = "Created Successfully" def get_form_kwargs(self): """ Add the Request object to the Form's Keyword Arguments. """ kwargs = super(RequestCreateView, self).get_form_kwargs() kwargs.update({'request': self.request}) return kwargs class RequestUpdateView(MessageMixin, UpdateView): """ Sub-class the UpdateView to pass the request to the form and limit the queryset to the requesting user. """ success_message = "Updated Successfully" def get_form_kwargs(self): """ Add the Request object to the form's keyword arguments. """ kwargs = super(RequestUpdateView, self).get_form_kwargs() kwargs.update({'request': self.request}) return kwargs def get_queryset(self): """ Limit a User to only modifying their own data. """ qs = super(RequestUpdateView, self).get_queryset() return qs.filter(owner=self.request.user) class RequestDeleteView(MessageMixin, DeleteView): """ Sub-class the DeleteView to restrict a User from deleting other user's data. """ success_message = "Deleted Successfully" def get_queryset(self): qs = super(RequestDeleteView, self).get_queryset() return qs.filter(owner=self.request.user)
用法
然后,您可以轻松创build自己的视图来使用这种types的function。 例如,我只是在我的urls.py中创build它们:
from myproject.utils.views import RequestDeleteView #... url(r'^delete-photo/(?P<pk>[\w]+)/$', RequestDeleteView.as_view( model=Photo, success_url='/site/media/photos', template_name='site/media-photos-delete.html', success_message='Your Photo has been deleted successfully.' ), name='fireflie-delete-photo-form'),
forms
重要的是要注意:我已经重载了那些get_form_kwargs()方法来为我的表单提供一个“请求”的实例。 如果您不希望将Request对象传递给Form,只需删除那些重载的方法即可。 如果您想使用它们,请按照以下示例进行操作:
from django.forms import ModelForm class RequestModelForm(ModelForm): """ Sub-class the ModelForm to provide an instance of 'request'. It also saves the object with the appropriate user. """ def __init__(self, request, *args, **kwargs): """ Override init to grab the request object. """ self.request = request super(RequestModelForm, self).__init__(*args, **kwargs) def save(self, commit=True): m = super(RequestModelForm, self).save(commit=False) m.owner = self.request.user if commit: m.save() return m
这比你提出的要多一点 – 但是知道如何为创build和更新视图做同样的工作也是很有帮助的。 同样的一般方法也可以应用于ListView和DetailView。
MessageMixin
以防万一任何人想要我使用的MessageMixin。
class MessageMixin(object): """ Make it easy to display notification messages when using Class Based Views. """ def delete(self, request, *args, **kwargs): messages.success(self.request, self.success_message) return super(MessageMixin, self).delete(request, *args, **kwargs) def form_valid(self, form): messages.success(self.request, self.success_message) return super(MessageMixin, self).form_valid(form)
我build议最好的(也是最简单的)方法是使用UserPassesTestMixin
,它可以让你更UserPassesTestMixin
分离关注点。
例:
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.views.generic import DeleteView class MyDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView): def test_func(self): """ Only let the user access this page if they own the object being deleted""" return self.get_object().owner == self.request.user
最简单的方法是预过滤查询集:
from django.views.generic import DeleteView class PostDeleteView(DeleteView): model = Post success_url = reverse_lazy('blog:list_post') def get_queryset(self): owner = self.request.user return self.model.objects.filter(owner=owner)