Django
クラスベースのビュー
サーチ…
備考
CBVを使用する場合、それぞれのジェネリッククラスに対してどのメソッドを上書きできるかを正確に知る必要があることがよくあります。 このページのdjangoドキュメントには、すべてのメソッドがフラット化されたジェネリッククラスと、使用できるクラス属性がリストされています。
さらに、 Classy Class Based Viewの Webサイトでは、素晴らしいインタラクティブなインターフェイスで同じ情報を提供しています。
クラスベースのビュー
クラスベースのビューでは、ビューを特別なものにするために焦点を当てることができます。
静的なページについては、使用されるテンプレートを除いて特別なものはありません。 TemplateViewを使用してください!テンプレート名を設定するだけです。ジョブが完了しました。次。
views.py
from django.views.generic import TemplateView
class AboutView(TemplateView):
template_name = "about.html"
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url('^about/', views.AboutView.as_view(), name='about'),
]
URLにAboutView
を直接使用しない方法に注目してください。これは、呼び出し可能であることが期待されるため、 as_view()
返すものです。
コンテキストデータ
場合によっては、テンプレートにもう少し情報が必要な場合もあります。たとえば、ユーザーのページヘッダーに、ログアウトリンクの横にプロファイルへのリンクがあるようにしたいとします。このような場合は、 get_context_data
メソッドを使用してget_context_data
。
views.py
class BookView(DetailView):
template_name = "book.html"
def get_context_data(self, **kwargs)
""" get_context_data let you fill the template context """
context = super(BookView, self).get_context_data(**kwargs)
# Get Related publishers
context['publishers'] = self.object.publishers.filter(is_active=True)
return context
スーパークラスでget_context_dataメソッドを呼び出す必要があり、デフォルトのコンテキストインスタンスが返されます。このディクショナリに追加するアイテムはすべてテンプレートで使用できます。
book.html
<h3>Active publishers</h3>
<ul>
{% for publisher in publishers %}
<li>{{ publisher.name }}</li>
{% endfor %}
</ul>
リストビューと詳細ビュー
テンプレートビューは静的なページではうまくいくので、 get_context_data
使ってすべてのテンプレートビューを使用することができますが、関数をビューとして使用するよりもget_context_data
良いでしょう。
app / models.py
from django.db import models
class Pokemon(models.Model):
name = models.CharField(max_length=24)
species = models.CharField(max_length=48)
slug = models.CharField(max_length=48)
app / views.py
from django.views.generic import ListView, DetailView
from .models import Pokemon
class PokedexView(ListView):
""" Provide a list of Pokemon objects """
model = Pokemon
paginate_by = 25
class PokemonView(DetailView):
model = Pokemon
それは、モデルのすべてのオブジェクトと単数形のビューをリスト表示するビューを生成するために必要なすべてです。リストにもページが区切られています。特定のものが必要な場合は、 template_name
できます。デフォルトでは、モデル名から生成されます。
app / templates / app / pokemon_list.html
<!DOCTYPE html>
<title>Pokedex</title>
<ul>{% for pokemon in pokemon_list %}
<li><a href="{% url "app:pokemon" pokemon.pk %}">{{ pokemon.name }}</a>
– {{ pokemon.species }}
</ul>
コンテキストには、 object_list
という2つの名前のオブジェクトのリストとモデル名の2つ目のbuild(ここではpokemon_list
ます。あなたがリストを改ページした場合は、次のリンクと前のリンクも処理する必要があります。 Paginatorオブジェクトはそれを助けることができます。コンテキストデータでも使用できます。
app / templates / app / pokemon_detail.html
<!DOCTYPE html>
<title>Pokemon {{ pokemon.name }}</title>
<h1>{{ pokemon.name }}</h1>
<h2>{{ pokemon.species }} </h2>
前と同じように、コンテクストには名前object
とpokemon
下にモデルオブジェクトが挿入されます。 pokemon
はモデル名から派生しています。
app / urls.py
from django.conf.urls import url
from . import views
app_name = 'app'
urlpatterns = [
url(r'^pokemon/$', views.PokedexView.as_view(), name='pokedex'),
url(r'^pokemon/(?P<pk>\d+)/$', views.PokemonView.as_view(), name='pokemon'),
]
このスニペットでは、詳細ビューのURLは主キーを使用して作成されています。引数としてスラッグを使用することもできます。これは、覚えやすい、より良い見た目のURLを提供します。ただし、モデルにはslugという名前のフィールドが必要です。
url(r'^pokemon/(?P<slug>[A-Za-z0-9_-]+)/$', views.PokemonView.as_view(), name='pokemon'),
フィールド場合はslug
存在しない場合は、使用することができますslug_field
に設定DetailView
別のフィールドを指すように。
ページネーションには、ページ取得パラメータを使用するか、URLに直接ページを配置します。
フォームとオブジェクトの作成
オブジェクトを作成するためのビューを書くことは非常に退屈です。フォームを表示する必要があります。フォームを検証する必要があります。アイテムを保存するか、エラーが発生したフォームを返す必要があります。 一般的な編集ビューのいずれかを使用しない限り。
app / views.py
from django.core.urlresolvers import reverse_lazy
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from .models import Pokemon
class PokemonCreate(CreateView):
model = Pokemon
fields = ['name', 'species']
class PokemonUpdate(UpdateView):
model = Pokemon
fields = ['name', 'species']
class PokemonDelete(DeleteView):
model = Pokemon
success_url = reverse_lazy('pokedex')
CreateView
とUpdateView
は、2つの必須の属性、 model
、およびfields
ありfields
。デフォルトでは、どちらも '_form'の接尾辞の付いたモデル名に基づいてテンプレート名を使用します。 template_name_suffix属性で接尾辞のみを変更できます。 DeleteViewは、オブジェクトを削除する前に確認メッセージを表示します。
UpdateView
とDeleteView
両方でオブジェクトをフェッチする必要があります。それらはDetailView
と同じメソッドを使用し、URLから変数を抽出し、オブジェクトフィールドを照合します。
app / templates / app / pokemon_form.html(解凍)
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>
form
は、必要なすべてのフィールドを含むform
が含まれています。ここでは、 as_p
ためにフィールドごとに段落が表示されます。
app / templates / app / pokemon_confirm_delete.html(解凍)
<form action="" method="post">
{% csrf_token %}
<p>Are you sure you want to delete "{{ object }}"?</p>
<input type="submit" value="Confirm" />
</form>
csrf_token
タグは、要求偽造に対するdjangoの保護のために必要です。フォームを表示しているURLが削除/保存を処理しているURLと同じであるため、属性アクションは空のままです。
リストと詳細例と同じものを使用する場合、モデルには2つの問題が残っています。まず、createとupdateは、リダイレクトURLが見つからないと不平を言うでしょう。それはポケモンモデルにget_absolute_url
を追加することで解決できます。第2の問題は、削除確認が意味のある情報を表示しないことです。これを解決するには、文字列表現を追加するのが最も簡単な方法です。
app / models.py
from django.db import models
from django.urls import reverse
from django.utils.encoding import python_2_unicode_compatible
@python_2_unicode_compatible
class Pokemon(models.Model):
name = models.CharField(max_length=24)
species = models.CharField(max_length=48)
def get_absolute_url(self):
return reverse('app:pokemon', kwargs={'pk':self.pk})
def __str__(self):
return self.name
クラスデコレータは、すべてがPython 2の下で円滑に動作することを確認します。
最小の例
views.py :
from django.http import HttpResponse
from django.views.generic import View
class MyView(View):
def get(self, request):
# <view logic>
return HttpResponse('result')
urls.py :
from django.conf.urls import url
from myapp.views import MyView
urlpatterns = [
url(r'^about/$', MyView.as_view()),
]
Djangoクラスベースのビュー:CreateViewの例
クラスベースの汎用ビューでは、モデルからCRUDビューを作成するのは非常に簡単で簡単です。多くの場合、組み込みのDjango管理者は十分ではないか、好まれず、独自のCRUDビューをロールバックする必要があります。そのような場合、CBVは非常に便利です。
CreateView
クラスには、モデル、使用するフィールド、成功URLという3つのものが必要です。
例:
from django.views.generic import CreateView
from .models import Campaign
class CampaignCreateView(CreateView):
model = Campaign
fields = ('title', 'description')
success_url = "/campaigns/list"
作成が成功すると、ユーザーはsuccess_url
リダイレクトされます。また、メソッドの定義することができますget_success_url
代わりにして使用しreverse
またはreverse_lazy
成功URLを取得します。
このビューのテンプレートを作成する必要があります。テンプレートの名前は、 <app name>/<model name>_form.html
の形式で指定する必要があります。モデル名は下限にする必要があります。たとえば、自分のアプリ名がdashboard
場合、上記の作成ビューでは、 dashboard/campaign_form.html
という名前のテンプレートを作成する必要があります。
テンプレートでは、 form
変数にはform
が含まれます。テンプレートのサンプルコードは次のとおりです。
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" />
</form>
今度は、URLパターンにビューを追加します。
url('^campaign/new/$', CampaignCreateView.as_view(), name='campaign_new'),
URLにアクセスすると、選択したフィールドのフォームが表示されます。提出すると、データでモデルの新しいインスタンスを作成して保存しようとします。成功すると、ユーザーは成功URLにリダイレクトされます。エラーが発生すると、エラーメッセージと共にフォームが再度表示されます。
1つのビュー、複数のフォーム
1つのDjangoビューで複数のフォームを使用する簡単な例を次に示します。
from django.contrib import messages
from django.views.generic import TemplateView
from .forms import AddPostForm, AddCommentForm
from .models import Comment
class AddCommentView(TemplateView):
post_form_class = AddPostForm
comment_form_class = AddCommentForm
template_name = 'blog/post.html'
def post(self, request):
post_data = request.POST or None
post_form = self.post_form_class(post_data, prefix='post')
comment_form = self.comment_form_class(post_data, prefix='comment')
context = self.get_context_data(post_form=post_form,
comment_form=comment_form)
if post_form.is_valid():
self.form_save(post_form)
if comment_form.is_valid():
self.form_save(comment_form)
return self.render_to_response(context)
def form_save(self, form):
obj = form.save()
messages.success(self.request, "{} saved successfully".format(obj))
return obj
def get(self, request, *args, **kwargs):
return self.post(request, *args, **kwargs)