动态的图片提供视图

Dynamic image serve view

在多数场合,想要在Python中生成图片副本的开发者,都应使用get_rendition()方法,请参考以Python方式生成图片转写

在需要为某种诸如博客或移动应用这样的 外部 系统生成图片的一些版本时,Wagtail提供了一种通过调用独特的URL,来动态生成图片副本的视图。

此种视图获取到URL中的图片id、过滤器规范与安全性签名。在这些参数为有效的情况下,将提供一个符合条件的图片文件。

{% image %}标签一样,该图片副本是在第一次调用时生成的,后续调用将从缓存中予以提供。

设置

将该视图的一个条目,添加到站点URLs配置中:

  1. # app/urls.py
  2. from wagtail.images.views.serve import ServeView
  3. urlpatterns = [
  4. ...
  5. url(r'^images/([^/]*)/(\d*)/([^/]*)/[^/]*$', ServeView.as_view(), name='wagtailimages_serve'),
  6. ...
  7. # 确保该 wagtailimages_serve 行,出现在默认Wagtail页面服务路由之上
  8. # Ensure that the wagtailimages_serve line appears above the default Wagtail page serving route
  9. url(r'', include(wagtail_urls)),
  10. ]

用法

图片URL生成器的UI

在开启了动态提供图片特性之后,在管理界面中的图片URL生成器将自动变为可用。可经由任意图片的编辑页面,通过点击右侧的“URL生成器”按钮,访问到图片URL生成器。

该界面令到站点编辑可以生成到图片裁剪版本的URLs。

以Python方式,生成动态的图片URLs

也可使用Python代码来生成动态的图片URLs,并经由API加以提供,或直接在模板中进行使用。

在模板中使用动态的图片URLs的一个优势,就是在渲染时不会像{% image %}标签那样阻塞到初次响应。

wagtail.images.views.serve中的generate_image_url函数,是生成动态的图片URL的一种方便的方法。

下面是在某个视图中该函数的使用示例:

  1. def display_image(request, image_id):
  2. image = get_object_or_404(Image, id=image_id):
  3. return render(request, 'display_image.html', {
  4. 'image_url': generated_image_url(image, 'fill-100x100')
  5. })

对图片的操作,可通过将这些操作以|字符连接起来的方式,链接起来:

  1. return render(request, 'display_image.html', {
  2. 'image_url': generate_image_url(image, 'fill-100x100|jpegquality-40')
  3. })

在模板中:

{% raw %}

  1. {% load wagtailimages_tags %}
  2. ...
  3. <!-- 获取所放到宽度400像素的图片的url -->
  4. {% image_url page.photo "width-400" %}
  5. <!-- 再获取一次,但这次作为一个方形的缩略图: -->
  6. {% image_url page.photo "fill-100x100|jpegquality-40" %}
  7. <!-- 这次使用定制的图片提供视图 -->
  8. {% image_url page.photo "width-400" "mycustomview_serve" %}

{% endraw %}

可传递一个将用于经由其提供图片的可选视图名称。默认的视图名称为wagtailimages_serve

高级配置

令到视图重定向而非直接提供

Making the view redirect instead of serve

默认下该视图将直接提供图片文件。此行为可修改为一个301重定向,在图片留存于外部主机时,这样做会有用处。

要开启重定向,就要在urls配置中,将action='redirect'传递给ServeView.as_view()方法:

  1. from wagtail.images.views.serve import ServeView
  2. urlpatterns = [
  3. ...
  4. url(r'^images/([^/*])/(\d*)/[^/*]/[^/]*$', ServeView.as_view(action='redirect'), name='wagtailimages_serve'),
  5. ]

django-sendfile的集成

django-sendfile 可将图片数据传输工作交给web服务器,而不是直接由Django应用直接提供图片数据。在站点有着很多同时被下载的图片,却又无法使用带有缓存的代理服务器或CDN的情况下,这样做可极大地减低服务器负载。

首先要安装和配置好django-sendfile,并将web服务器配置好使用django-sendfile。如尚未准备好这些,请参考该安装文档

可使用SenfFileView类,来以django-sendfile方式进行图片的提供。此视图可开箱即用:

  1. from wagtail.images.views.serve import SendFileView
  2. urlpatterns = [
  3. ...
  4. url(r'^images/([^/]*)/(\d*)/([^/]*)/[^/]*$', SendFileView.as_view(), name='wagtailimages_serve'),
  5. ]

可对其加以定制,以对SENDFILE_BACKEND中定义的后端进行覆写:

  1. from wagtail.images.views.serve import SendFileView
  2. from project.sendfile_backends import MyCustomBackend
  3. class MySendFileView(SendFileView):
  4. backend = MyCustomBackend

还可将其定制为发送私有文件。比如在要求仅为要求认证(例如对于Django >= 1.9):

  1. from django.contrib.auth.mixins import LoginRequiredMixin
  2. from wagtail.images.views.serve import SendFileView
  3. class PrivateSendFileView(LoginRequiredMixin, SendFileView):
  4. raise_exception = True