2013-04-02 30 views
55

Django 1.5のクラスベースのビューでURLパラメータにアクセスするにはどうすればよいか不明です。私は私の見解でyearパラメータにアクセスしたいので、私はロジックを行うことができますDjangoクラスベースのビュー(TemplateView)のURLパラメータとロジック

from .views import Yearly 


urlpatterns = patterns('', 
    url(
     regex=r'^(?P<year>\d+)/$', 
     view=Yearly.as_view(), 
     name='yearly-view' 
    ), 
) 

ビュー:

from django.views.generic.base import TemplateView 


class Yearly(TemplateView): 
    template_name = "calendars/yearly.html" 

    current_year = datetime.datetime.now().year 
    current_month = datetime.datetime.now().month 

    def get_context_data(self, **kwargs): 
     context = super(Yearly, self).get_context_data(**kwargs) 
     context['current_year'] = self.current_year 
     context['current_month'] = self.current_month 
     return context 

のURLconf

は、次のことを考えてみましょうlike:

month_names = ["January", "February", "March", "April", "May", "June", "July", 
       "August", "September", "October", "November", "December"] 

    for month, month_name in enumerate(month_names, start=1): 
     is_current = False 
     if year == current_year and month == current_month: 
      is_current = True 
     months.append({ 
      'month': month, 
      'name': month_name, 
      'is_current': is_current}) 

TemplateViewという上記のようなCBVsのurlパラメータへのアクセス方法と、このようなロジックを理想的に配置する必要がある場所はどれですか。方法で?

答えて

71

self.argsまたはself.kwargsを使用して、クラス内のURLパラメータに基づいて、ビューにアクセスするので、あなたはこれまでのところ、私は唯一ものの、get_querysetメソッド内からこれらのURLのパラメータにアクセスすることができましたself.kwargs['year']

+1

私は上記のようにビューに直接変数を作成するはずがないことを正しく理解していますか? (彼らについての何かが永続的なもの)。また、私は上記のようなロジックを配置する場所を理解していません。どちらの方法で?また、 'year = self.kwargs ['year']'というビューで 'NameError:self not defined'を取得します。 –

+2

技術的には、それらはクラスレベルにあり、クラス変数であるため、使用すべきではありません。 'NameError'に関しては、' year = self.kwargs ['year'] 'をしようとしていますか?メソッドでそれをやっているはずです。クラスレベルではできません。たとえば、 'TemplateView'を使用しています。つまり、' get_context_data'オーバーライドでロジックを行うことになります。 – Ngenator

+2

参照用:self.request、self.argsなどのドキュメントはhttps://docs.djangoproject.com/en/1.10/topics/class-based-views/generic-display/にあります。 – LShi

7

をすることによってそれにアクセスします私は、TemplateViewではなくListViewで試してみました。私は、コンテキストを移入するget_context_dataにその属性を使用して、オブジェクトインスタンスの属性を作成するためのURLのparamを使用します:

class Yearly(TemplateView): 
    template_name = "calendars/yearly.html" 

    current_year = datetime.datetime.now().year 
    current_month = datetime.datetime.now().month 

    def get_queryset(self): 
     self.year = self.kwargs['year'] 
     queryset = super(Yearly, self).get_queryset() 
     return queryset 

    def get_context_data(self, **kwargs): 
     context = super(Yearly, self).get_context_data(**kwargs) 
     context['current_year'] = self.current_year 
     context['current_month'] = self.current_month 
     context['year'] = self.year 
     return context 
+0

あなたが 'context ['year'] = self.kwargs ['year']'を実行しようとすると、奇妙なことにエラーや何かがありますか?クラス内のどこにでもアクセス可能でなければなりません。 – Ngenator

+0

@Ngenator:私はちょうどクリーンなdjangoプロジェクトをダブルチェックするように設定しました。あなたが正しいと分かりました。私は元のコードで何がこれを防ぐのか分からないが、私は見つけ出すだろう:)。ヘッドアップありがとう – hellsgate

37

あなたはこのようにURLパラメータを渡す場合:

http://<my_url>/?order_by=created 

をあなたは(そのself.argsにもself.kwargsに提示されていない)self.request.GETを使用して、クラスに基づいてビューにアクセスすることができます:

class MyClassBasedView(ObjectList): 
    ... 
    def get_queryset(self): 
     order_by = self.request.GET.get('order_by') or '-created' 
     qs = super(MyClassBasedView, self).get_queryset() 
     return qs.order_by(order_by) 
+2

ありがとう!これは私を混乱させています...私はHTTPパラメータがkwargsになることを意味するものを読んでいます。 – foobarbecue

+0

MyClassBasedViewのスーパークラスのget_queryset()を表示できますか?私は 'qs = .objectsを実行します。 ' – Timo

15

私はこれを見つけましたhereを指摘したように、とDjango 1.5以上のためのエレガントなソリューション、:あなたのviews.pyで

Django’s generic class based views now automatically include a view variable in the context. This variable points at your view object.

:このquestionで見つかった

from django.views.generic.base import TemplateView  

class Yearly(TemplateView): 
    template_name = "calendars/yearly.html" 
    # No here 
    current_year = datetime.datetime.now().year 
    current_month = datetime.datetime.now().month 

    # dispatch is called when the class instance loads 
    def dispatch(self, request, *args, **kwargs): 
     self.year = kwargs.get('year', "any_default") 

    # other code 

派遣ソリューション。
viewはすでにテンプレートコンテキスト内で渡されているため、実際には気にする必要はありません。そのままあなたがあなたのURLconfを保つことができる

{{ view.year }} 
{{ view.current_year }} 
{{ view.current_month }} 

:あなたのテンプレートファイルyearly.htmlでは、これらのビューがするだけで属性にアクセスすることが可能です。

テンプレートのコンテキストに情報を取得するとget_context_data()が上書きされるので、DjangoのアクションBeanを何とか破棄しています。フロー。

関連する問題