Djangoのクラスベースの汎用DeleteViewの簡単な例を作成できる人はいますか? DeleteViewをサブクラス化し、現在ログインしているユーザーがオブジェクトを削除する前に所有権を持っていることを確認します。どんな助けも大歓迎です。前もって感謝します。
以下に簡単なものを示します。
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
要求では削除されません。これは、POST
sをこのビューに表示する「Yes I's sure」ボタンを使用して、確認テンプレート(template_name
クラス属性で名前を指定できます)を提供する機会です。delete
メソッドをオーバーライドし、get_object
呼び出しの後に許可を確認し、カスタマイズされた応答を返します。success_url
クラス属性に一致するテンプレートを提供することを忘れないでください。基本的に、これを行うために、いくつかの汎用クラスベースビューをサブクラス化しました。主な違いは、クエリセットを除外しただけです。この方法が良いか悪いかを保証することはできませんが、私にとってはより意味がありました。
「MessageMixin」は無視してください。Django各ビューに指定された変数を使用したメッセージングフレームワークを使用して、メッセージを簡単に表示できます。 :
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)
その後、このタイプの機能を使用する独自のビューを簡単に作成できます。たとえば、urls.pyで作成しています。
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に 'request'のインスタンスを提供するために、これらのget_form_kwargs()メソッドをオーバーロードしました。 Requestオブジェクトをフォームに渡したくない場合は、それらのオーバーロードされたメソッドを削除してください。それらを使用する場合は、次の例を参照してください。
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
これは、あなたが尋ねたものよりも少し多くありますが、作成ビューと更新ビューでも同じことを行う方法を知るのに役立ちます。これと同じ一般的な方法論は、ListViewとDetailViewにも適用できます。
私が使用する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)
これを行う最も簡単な方法は、クエリセットを事前フィルタリングすることです。
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)
これを行うための最良の(そして最も簡単な)方法は、 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