HTMLとフォーム
REST frameworkは、APIスタイルのレスポンスと通常のHTMLページの両方を返すのに適しています。さらに、シリアライザーはHTMLフォームとして使用でき、テンプレートでレンダリングできます。
HTMLのレンダリング
HTMLレスポンスを返すには、TemplateHTMLRenderer
またはStaticHTMLRenderer
を使用する必要があります。
TemplateHTMLRenderer
クラスは、レスポンスにコンテキストデータの辞書が含まれていることを期待し、ビューまたはレスポンスで指定する必要があるテンプレートに基づいてHTMLページをレンダリングします。
StaticHTMLRender
クラスは、レスポンスに事前にレンダリングされたHTMLコンテンツの文字列が含まれていることを期待します。
静的なHTMLページは通常、APIレスポンスとは異なる動作をするため、組み込みのジェネリックビューに依存するのではなく、HTMLビューを明示的に記述する必要があるでしょう。
"Profile"インスタンスのリストをHTMLテンプレートでレンダリングして返すビューの例を次に示します。
views.py:
from my_project.example.models import Profile
from rest_framework.renderers import TemplateHTMLRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
class ProfileList(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'profile_list.html'
def get(self, request):
queryset = Profile.objects.all()
return Response({'profiles': queryset})
profile_list.html:
<html><body>
<h1>Profiles</h1>
<ul>
{% for profile in profiles %}
<li>{{ profile.name }}</li>
{% endfor %}
</ul>
</body></html>
フォームのレンダリング
シリアライザーは、render_form
テンプレートタグを使用してフォームとしてレンダリングし、テンプレートにシリアライザーインスタンスをコンテキストとして含めることができます。
次のビューは、モデルインスタンスの表示と更新のためにテンプレートでシリアライザーを使用する例を示しています。
views.py:
from django.shortcuts import get_object_or_404
from my_project.example.models import Profile
from rest_framework.renderers import TemplateHTMLRenderer
from rest_framework.views import APIView
class ProfileDetail(APIView):
renderer_classes = [TemplateHTMLRenderer]
template_name = 'profile_detail.html'
def get(self, request, pk):
profile = get_object_or_404(Profile, pk=pk)
serializer = ProfileSerializer(profile)
return Response({'serializer': serializer, 'profile': profile})
def post(self, request, pk):
profile = get_object_or_404(Profile, pk=pk)
serializer = ProfileSerializer(profile, data=request.data)
if not serializer.is_valid():
return Response({'serializer': serializer, 'profile': profile})
serializer.save()
return redirect('profile-list')
profile_detail.html:
{% load rest_framework %}
<html><body>
<h1>Profile - {{ profile.name }}</h1>
<form action="{% url 'profile-detail' pk=profile.pk %}" method="POST">
{% csrf_token %}
{% render_form serializer %}
<input type="submit" value="Save">
</form>
</body></html>
テンプレートパックの使用
render_form
タグは、フォームとフォームフィールドのレンダリングに使用するテンプレートディレクトリを指定するオプションのtemplate_pack
引数を受け取ります。
REST frameworkには、すべてBootstrap 3に基づいた3つの組み込みテンプレートパックが含まれています。組み込みスタイルはhorizontal
、vertical
、inline
です。デフォルトスタイルはhorizontal
です。これらのテンプレートパックを使用するには、Bootstrap 3 CSSも含める必要があります。
次のHTMLは、Bootstrap 3 CSSのCDNホストバージョンへのリンクです。
<head>
…
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
サードパーティパッケージは、必要なフォームとフィールドテンプレートを含むテンプレートディレクトリをバンドルすることで、代替テンプレートパックを含めることができます。
利用可能な3つのテンプレートパックをそれぞれレンダリングする方法を見てみましょう。これらの例では、「ログイン」フォームを表示するために単一のシリアライザークラスを使用します。
class LoginSerializer(serializers.Serializer):
email = serializers.EmailField(
max_length=100,
style={'placeholder': 'Email', 'autofocus': True}
)
password = serializers.CharField(
max_length=100,
style={'input_type': 'password', 'placeholder': 'Password'}
)
remember_me = serializers.BooleanField()
rest_framework/vertical
標準のBootstrapレイアウトを使用して、対応するコントロール入力の上にフォームラベルを表示します。
これはデフォルトのテンプレートパックです。
{% load rest_framework %}
...
<form action="{% url 'login' %}" method="post" novalidate>
{% csrf_token %}
{% render_form serializer template_pack='rest_framework/vertical' %}
<button type="submit" class="btn btn-default">Sign in</button>
</form>
rest_framework/horizontal
2/10列の分割を使用して、ラベルとコントロールを並べて表示します。
これは、ブラウズ可能なAPIと管理者レンダラーで使用されるフォームスタイルです。
{% load rest_framework %}
...
<form class="form-horizontal" action="{% url 'login' %}" method="post" novalidate>
{% csrf_token %}
{% render_form serializer %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Sign in</button>
</div>
</div>
</form>
rest_framework/inline
すべてのコントロールをインラインで表示するコンパクトなフォームスタイルです。
{% load rest_framework %}
...
<form class="form-inline" action="{% url 'login' %}" method="post" novalidate>
{% csrf_token %}
{% render_form serializer template_pack='rest_framework/inline' %}
<button type="submit" class="btn btn-default">Sign in</button>
</form>
フィールドスタイル
シリアライザーフィールドは、style
キーワード引数を使用してレンダリングスタイルをカスタマイズできます。この引数は、使用されるテンプレートとレイアウトを制御するオプションの辞書です。
フィールドスタイルをカスタマイズする最も一般的な方法は、base_template
スタイルキーワード引数を使用して、テンプレートパック内のどのテンプレートを使用するかを選択することです。
たとえば、CharField
をデフォルトのHTML入力ではなくHTMLテキストエリアとしてレンダリングするには、次のようなものを使用します。
details = serializers.CharField(
max_length=1000,
style={'base_template': 'textarea.html'}
)
代わりに、含まれているテンプレートパックの一部ではないカスタムテンプレートを使用してフィールドをレンダリングする場合は、template
スタイルオプションを使用してテンプレート名を完全に指定できます。
details = serializers.CharField(
max_length=1000,
style={'template': 'my-field-templates/custom-input.html'}
)
フィールドテンプレートは、そのタイプに応じて追加のスタイルプロパティを使用することもできます。たとえば、textarea.html
テンプレートは、コントロールのサイズに影響を与えるために使用できるrows
プロパティも受け入れます。
details = serializers.CharField(
max_length=1000,
style={'base_template': 'textarea.html', 'rows': 10}
)
base_template
オプションとその関連するスタイルオプションの完全なリストを以下に示します。
base_template | 有効なフィールドタイプ | 追加のスタイルオプション |
---|---|---|
input.html | 任意の文字列、数値、または日付/時刻フィールド | input_type、placeholder、hide_label、autofocus |
textarea.html | CharField |
rows、placeholder、hide_label |
select.html | ChoiceField またはリレーショナルフィールドタイプ |
hide_label |
radio.html | ChoiceField またはリレーショナルフィールドタイプ |
inline、hide_label |
select_multiple.html | MultipleChoiceField またはmany=True を持つリレーショナルフィールド |
hide_label |
checkbox_multiple.html | MultipleChoiceField またはmany=True を持つリレーショナルフィールド |
inline、hide_label |
checkbox.html | BooleanField |
hide_label |
fieldset.html | ネストされたシリアライザー | hide_label |
list_fieldset.html | ListField またはmany=True を持つネストされたシリアライザー |
hide_label |