55

DjangoのクラスベースのジェネリックDeleteViewの簡単な例を知っている人はいますか? DeleteView をサブクラス化し、現在ログインしているユーザーが削除される前にオブジェクトの所有権を持っていることを確認したいと考えています。どんな助けでも大歓迎です。前もって感謝します。

4

4 に答える 4

63

ここに簡単なものがあります:

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に「はい、そうです」ボタンを付けますPOST
  • 404 よりもエラー メッセージの方が好きかもしれません。この場合、代わりにメソッドをオーバーライドし、呼び出しdelete後に権限を確認して、カスタマイズされた応答を返します。get_object
  • success_urlユーザーがオブジェクトが削除されたことを確認できるように、(オプションでカスタマイズ可能な) class 属性に一致するテンプレートを提供することを忘れないでください。
于 2011-04-03T20:54:19.527 に答える
44

私は基本的に、正確にそれを行うために、ジェネリック クラスベース ビューのいくつかをサブクラス化しました。主な違いは、クエリセットを除外したことです。この方法が良いか悪いかは保証できませんが、私にとってはより理にかなっています。

「MessageMixin」は無視してかまいません。これは、Django Messaging Framework を使用して、ビューごとに変数を指定してメッセージを簡単に表示するためのものです。私たちのサイト用に書いたコードは次のとおりです。

ビュー

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'),

フォーム

注意すべき重要事項:これらの 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

これはあなたが要求したよりも少し多いですが、Create ビューと Update ビューについても同じことを行う方法を知っておくと役に立ちます。この同じ一般的な方法論は、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)
于 2012-06-05T19:50:34.163 に答える