40

オブジェクトの更新作成の両方を行うクラス ベースのビューを作成したいとします。以前の質問から、次のいずれかを実行できることがわかりました。

1) 2 つの一般的なビューCreateViewを使用UpdateViewします。これは、2 つの異なるクラスを指す 2 つの URL を持つことを意味すると思います。

2) base を継承するクラスベースのビューを使用しますView。これは、1 つのクラスだけを指す 2 つの URL を持つことを意味すると思います (継承するものを作成しましたView)。

2 つの質問があります。

a) どちらが良いですか?

b) ccbv.co.ukには baseViewが表示されていますが、get や post などのメソッドが文書化されていません。これは正しいですか?

4

7 に答える 7

57

こういうものが欲しくなる場面に出くわしました。これが私が思いついたものです(更新ビューとして使用しようとしていて、要求されたオブジェクトが見つからない場合、404をスローするのではなく、作成ビューとして動作することに注意してください):

from django.views.generic.detail import SingleObjectTemplateResponseMixin
from django.views.generic.edit import ModelFormMixin, ProcessFormView

class CreateUpdateView(
    SingleObjectTemplateResponseMixin, ModelFormMixin, ProcessFormView
):

    def get_object(self, queryset=None):
        try:
            return super(CreateUpdateView,self).get_object(queryset)
        except AttributeError:
            return None

    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super(CreateUpdateView, self).get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super(CreateUpdateView, self).post(request, *args, **kwargs)

まったく同じクラスと mixinUpdateViewを継承していることがわかりました。CreateView唯一の違いは、get/post メソッドにあります。Django ソース (1.8.2) で定義されている方法は次のとおりです。

class BaseCreateView(ModelFormMixin, ProcessFormView):
    """
    Base view for creating an new object instance.

    Using this base class requires subclassing to provide a response mixin.
    """
    def get(self, request, *args, **kwargs):
        self.object = None
        return super(BaseCreateView, self).get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.object = None
        return super(BaseCreateView, self).post(request, *args, **kwargs)


class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView):
    """
    View for creating a new object instance,
    with a response rendered by template.
    """
    template_name_suffix = '_form'


class BaseUpdateView(ModelFormMixin, ProcessFormView):
    """
    Base view for updating an existing object.

    Using this base class requires subclassing to provide a response mixin.
    """
    def get(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super(BaseUpdateView, self).get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        self.object = self.get_object()
        return super(BaseUpdateView, self).post(request, *args, **kwargs)


class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView):
    """
    View for updating an object,
    with a response rendered by template.
    """
    template_name_suffix = '_form'

ご覧のとおり、CreateView の get メソッドと post メソッドが設定されself.object = None、 が にUpdateView設定されていself.get_object()ます。私が行ったのは、オブジェクトがない場合に例外を発生させるのではなくCreateUpdateView.get_object、親クラスを呼び出そうとするメソッドでこれら2つを組み合わせてget_object返すことだけです。None

更新ビューとして使用するときに 404 ページを提供するには、おそらくオーバーライドしてブール値の引数as_viewを渡すことができます。であり、ビューがオブジェクトを見つけられないupdate_only場合は、404 を発生させます。update_onlyTrue

于 2015-06-19T22:29:42.063 に答える
2

単一のビューで作成と更新の両方を処理する必要があるのはなぜですか? それぞれのジェネリック ビュー クラスを継承する 2 つの個別のビューを用意する方がはるかに簡単です。必要に応じて、同じフォームとテンプレートを共有できます。また、異なる URL から提供される可能性が高いため、単一のビューにすると何が得られるかわかりません。

したがって、2 つのビューを使用します。1 つは から継承し、もう 1 つは から継承しCreateViewますUpdateView。これらは必要なほとんどすべてを処理しますが、2 番目のアプローチでは自分で車輪を再発明する必要があります。オブジェクトの作成または更新の両方で使用される一般的な「ハウスキーピング」コードがある場合、ミックスインを使用するオプション、またはCreateViewUpdateView.

于 2013-06-19T16:08:11.957 に答える
1

404 を発生させる必要がなく、オブジェクトが存在しない場合はすべてのフィールドを空白にしたい場合は、最初に保存するときにオブジェクトを作成し、存在するときに更新すると、これを使用できます。

ビュー.py

from django.views.generic import UpdateView


class CreateUpdateView(UpdateView):
    model = MyModel
    form_class = MyModelForm

    def get_object(self, queryset=None):
        return self.model.objects.filter(...).first()

フォーム.py

class MyModelForm(forms.ModelForm):

    class Meta:
        model = MyModel
        fields = [...]
于 2020-02-28T15:10:50.480 に答える
0

UpdateViewとの間でコードを共有するCreateViewには、結合されたクラスを作成する代わりに、共通のスーパークラスを mixin として使用できます。そうすれば、さまざまな懸念事項を簡単に分離できます。そして - 多くの既存の Django コードを再利用できます。

class BookFormView(PJAXContextMixin):
    template_name = 'library/book_form.html'
    form_class = BookForm

    def form_valid(self, form):
        form.instance.owner = self.request.user
        return super().form_valid(form)

    class Meta:
        abstract = True


class BookCreateView(BookFormView, CreateView):
    pass


class FormatUpdateView(BookFormView, UpdateView):
    queryset = Book.objects
于 2016-07-24T09:59:58.923 に答える
0

Django の CBV に触発された Django Smartmin を使用することもできます。ドキュメントの例を次に示します: https://smartmin.readthedocs.org/en/latest/quickstart.html

于 2015-10-06T07:31:27.190 に答える