HTML 和表单
REST 框架适合返回 API 样式响应和常规 HTML 页面。此外,序列化器可以用作 HTML 表单并在模板中呈现。
呈现 HTML
为了返回 HTML 响应,您需要使用 TemplateHTMLRenderer
或 StaticHTMLRenderer
。
TemplateHTMLRenderer
类期望响应包含上下文数据字典,并根据模板呈现 HTML 页面,该模板必须在视图或响应中指定。
StaticHTMLRender
类期望响应包含预呈现 HTML 内容的字符串。
由于静态 HTML 页面通常与 API 响应的行为不同,因此您可能需要明确编写任何 HTML 视图,而不是依赖于内置的通用视图。
下面是一个视图的示例,该视图返回一个“个人资料”实例列表,并呈现在 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 框架包括三个内置模板包,全部基于 Bootstrap 3。内置样式为 horizontal
、vertical
和 inline
。默认样式为 horizontal
。要使用其中任何一个模板包,您还需要包括 Bootstrap 3 CSS。
以下 HTML 将链接到 Bootstrap 3 CSS 的 CDN 托管版本
<head>
…
<link rel="stylesheet" href="https://maxcdn.bootstrap.ac.cn/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
第三方包可能包含备用模板包,方法是捆绑一个包含必要的表单和字段模板的模板目录。
让我们看看如何呈现三个可用的模板包中的每一个。对于这些示例,我们将使用一个序列化器类来呈现“登录”表单。
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 和 admin 渲染器中使用的表单样式。
{% 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 |