2017-06-24 13 views
0

1つのオブジェクトに関する情報を、各ビューのget_context_dataで繰り返さずに、多くのビューに入れたいとします。私はget_context_dataクラスを必要とすることを理解しているので、他のビューと混在することができます。 ここに私の例では、私はUpdateAnotherObjectViewの文脈における「some_object」を見てみたい:多くの異なるDjangoビューで同じコンテキストを挿入するには?

class BaseObjectInfoView(View): 
    def get_context_data(self, **kwargs): 
     context_data = super(BaseObjectInfoView, self).get_context_data(**kwargs) 
     context_data['some_object'] = SomeObjects.objects.get(pk=1) 
     return context_data 

class UpdateAnotherObjectView(BaseObjectInfo, UpdateView): 
    template_name = 'create_object.html' 
    form_class = AnotherObjectForm 
    model = AnotherObjects 

    def get_context_data(self, **kwargs): 
     context_data = super(UpdateAnotherObjectView, self).get_context_data(**kwargs) 
     context_data['all_another_objects'] = AnotherObjects.objects.all() 
     return context_data 

それは動作しますが、親の「表示」クラスの一部はget_context_dataではありません。 BaseObjectInfoViewから継承するために特別なクラスが必要なのでしょうか?

別の方法でコンテキストを構築する方が良いでしょうか?

答えて

0

ミックスインはビューである必要はありませんが、彼らは、彼らがオーバーライドしているメソッドを持っている場合、それはIDEのに役立ちます。

コンテキストは(this very handy siteの詳細)django.views.generic.base.ContextMixinによって処理されている、だから、物事のクラスベースのビューの方法は、このようになります:

from django.views import generic 

class WebsiteCommonMixin(generic.base.ContextMixin): 
    page_title = '' 
    active_menu = None 

    def get_context_data(self, **kwargs): 
     context = super(WebsiteCommonMixin, self).get_context_data(**kwargs) 
     context.update(dict(page_title=self.page_title, active_menu=self.active_menu)) 
     return context 

class NewsListView(WebsiteCommonMixin, ListView): 
    page_title = 'News list' 
    active_menu = 'News' 
    model = News 
    paginate_by = 12 

私はこれは多くのプロジェクト、あなたがとにかく作成する必要があり、単純なビューのために行います完全に宣言的です。そして、簡単に言うと、私はそれらが複数のミックスインで構成されていることを意味しています。すべてが、get_queryset、get_context_data、またはform_validのいずれかで難しいことをしています。もっと手の込んだ例、プロジェクトからまっすぐ:

class FeedbackMixin(object): 
    message = 'Well Done!' 

    def __init__(self): 
     self._message_kwargs = {} 
     super().__init__() 

    def add_message_kwarg(self, name, value) -> None: 
     self._message_kwargs[name] = value 

    def format_message(self, kwargs) -> str: 
     return self.message.format(**kwargs) 

    def generate_message(self) -> None: 
     msg = self.format_message(self._message_kwargs) 
     messages.success(getattr(self, 'request'), msg) 


class ModelFeedbackMixin(FeedbackMixin, generic.edit.ModelFormMixin): 
    success_view_name = None 
    success_url_kwargs = None 

    def get_success_url_kwargs(self): 
     return self.success_url_kwargs 

    def get_success_url(self) -> str: 
     success_url_kwargs = self.get_success_url_kwargs() 
     if not self.success_view_name: 
      url = super().get_success_url() 
     elif success_url_kwargs is not None: 
      url = reverse(self.success_view_name, kwargs=success_url_kwargs) 
     else: 
      if hasattr(self.object, 'slug'): 
       url_kwargs = {'slug': self.object.slug} 
      else: 
       url_kwargs = {'pk': self.object.pk} 
      url = reverse(self.success_view_name, kwargs=url_kwargs) 
     return url 

    def form_valid(self, form): 
     response = super().form_valid(form) 
     self.generate_message() 
     return response 
+0

とてもいいです!しかし、コンテキストmixinを使って管理するには、URLパターン(例: 'object_pk')に記述されているビューkwargsに依存するオブジェクトをコンテキストに配置する必要がありますか?私の例では、pk = 1でオブジェクトを取得しましたが、pkマストはURLから取得します。 –

+0

pkはビュー上で 'self.kwargs'で利用可能です。これは 'View.as_view()'によって行われます。しかし、「DetailView」の一部である[SingleObjectMixin](http://ccbv.co.uk/projects/Django/1.11/django.views.generic.detail/SingleObjectMixin/)は、もしあればあなたのために頑張ってくれます。ビューの主な目的。 – Melvyn

0

たぶん、この方法は、読みやすく可能性が...

def add_context(func): 
# this is a wrapper function 
    def wrapper(*args, **kwargs): 
     context_data = func(*args, **kwargs) 
     context_data['some_object'] = SomeObjects.objects.get(pk=1) 
     return context_data 
return wrapper 


class UpdateAnotherObjectView(BaseObjectInfo, UpdateView): 
    template_name = 'create_object.html' 
    form_class = AnotherObjectForm 
    model = AnotherObjects 

    @add_context 
    def get_context_data(self, **kwargs): 
     kwargs['all_another_objects'] = AnotherObjects.objects.all() 
     return kwargs 
関連する問題