サーチ…


備考

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良いでしょう。

ListViewDetailViewを入力

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>
        &ndash; {{ 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>

前と同じように、コンテクストには名前objectpokemon下にモデルオブジェクトが挿入されます。 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')

CreateViewUpdateViewは、2つの必須の属性、 model 、およびfieldsありfields 。デフォルトでは、どちらも '_form'の接尾辞の付いたモデル名に基づいてテンプレート名を使用します。 template_name_suffix属性で接尾辞のみを変更できます。 DeleteViewは、オブジェクトを削除する前に確認メッセージを表示します。

UpdateViewDeleteView両方でオブジェクトをフェッチする必要があります。それらは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ドキュメントの詳細»

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)


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow