跳转到主要内容

响应式跨浏览器图像库,使用现代代码如AVIF & WebP。

项目描述

Django Pictures Logo

Django Pictures

响应式跨浏览器图像库,使用现代代码如AVIF & WebP。

  • 使用picture标签进行响应式网页图像
  • 原生网格系统支持
  • 使用或不用CDN提供文件服务
  • 用于本地开发的占位符
  • 支持迁移
  • 针对CeleryDramatiqDjango RQ的异步图像处理
  • DRF 支持

PyPi Version Test Coverage GitHub License

使用方法

在开始之前,了解 响应式图片 的基本原理是个不错的主意。

一旦你感受到处理所有设备类型可能会多么复杂,你可能会对这款包有新的认识,并准备好将其应用于你的项目中 :)

# models.py
from django.db import models
from pictures.models import PictureField

class Profile(models.Model):
    title = models.CharField(max_length=255)
    picture = PictureField(upload_to="avatars")
<!-- template.html -->
{% load pictures %}
{% picture profile.picture img_alt="Spiderman" img_loading="lazy" picture_class="my-picture" m=6 l=4 %}

关键字参数 m=6 l=4 定义了图像在给定断点处应该占用的列数。所以在这个例子中,图像在中等屏幕上将占用 6 列,在大屏幕上将占用 4 列。你可以根据自己的需要定义网格和断点,请参考 网格列断点 部分。

上面的模板将渲染为

<picture class="my-picture">
  <source type="image/webp"
          srcset="/media/testapp/profile/image/800w.webp 800w, /media/testapp/profile/image/100w.webp 100w, /media/testapp/profile/image/200w.webp 200w, /media/testapp/profile/image/300w.webp 300w, /media/testapp/profile/image/400w.webp 400w, /media/testapp/profile/image/500w.webp 500w, /media/testapp/profile/image/600w.webp 600w, /media/testapp/profile/image/700w.webp 700w"
          sizes="(min-width: 0px) and (max-width: 991px) 100vw, (min-width: 992px) and (max-width: 1199px) 33vw, 600px">
  <img src="/media/testapp/profile/image.jpg" alt="Spiderman" width="800" height="800" loading="lazy">
</picture>

请注意,可以通过在 {% picture %} 标签的前缀参数中使用 picture_img_ 分别将任意属性传递给 <picture><img> 元素。

设置

安装

python3 -m pip install django-pictures

配置

# settings.py
INSTALLED_APPS = [
    # ...
    'pictures',
]

# the following are defaults, but you can override them
PICTURES = {
    "BREAKPOINTS": {
        "xs": 576,
        "s": 768,
        "m": 992,
        "l": 1200,
        "xl": 1400,
    },
    "GRID_COLUMNS": 12,
    "CONTAINER_WIDTH": 1200,
    "FILE_TYPES": ["WEBP"],
    "PIXEL_DENSITIES": [1, 2],
    "USE_PLACEHOLDERS": True,
    "QUEUE_NAME": "pictures",
    "PROCESSOR": "pictures.tasks.process_picture",

}

如果你已经安装了 Dramatiq 或 Celery,我们将默认使用异步图像处理。你需要工人来监听 pictures 队列。

占位符

此库附带动态创建的占位符,以简化本地开发。要启用它们,请将以下内容添加到启用 PICTURES["USE_PLACEHOLDERS"] 设置并添加以下 URL 配置

# urls.py
from django.urls import include, path
from pictures.conf import get_settings

urlpatterns = [
    # ...
]

if get_settings().USE_PLACEHOLDERS:
    urlpatterns += [
        path("_pictures/", include("pictures.urls")),
    ]

旧版使用案例(电子邮件)

尽管 picture 标签对大多数用例来说已经足够好了,但还有一些情况下,需要一个单独的 img 标签。特别是在电子邮件中,尽管 大多数客户端都支持 WebP,但并不支持 srcset。模板标签 img_url 返回单个尺寸的图像 URL。除了比例外,你还需要定义 file_type 以及 width(像素的绝对宽度)。

{% load pictures %}
<img src="{% img_url profile.picture ratio="3/2" file_type="webp" width=800 %}" alt="profile picture">

配置

纵横比

你可以指定图像的纵横比。图像将被裁剪到指定的纵横比。纵横比由一个包含宽度与高度之间斜杠的字符串指定。例如,16/9 将裁剪图像到 16:9。

# models.py
from django.db import models
from pictures.models import PictureField


class Profile(models.Model):
    title = models.CharField(max_length=255)
    picture = PictureField(
      upload_to="avatars",
      aspect_ratios=[None, "1/1", "3/2", "16/9"],
    )
# template.html
{% load pictures %}
{% picture profile.picture img_alt="Spiderman" ratio="16/9" m=6 l=4 %}

如果你在模板中没有指定纵横比或 None,图像将以文件的原始纵横比提供服务。

你只能在模板中使用在模型上定义的纵横比。如果提供其他值,则模型的 aspect_ratios 将默认为 [None]

断点

你可以定义自己的断点,它们应该与你在 css 库中使用的断点相同。只需覆盖 PICTURES["BREAKPOINTS"] 设置。

网格列

网格在网页设计中非常常见,甚至已经进入了 CSS。我们默认为 12 列,但你可以通过 PICTURES["GRID_COLUMNS"] 设置覆盖此设置。

容器宽度

容器通常用于限制布局的最大宽度,以促进在大屏幕上的可读性。我们默认为 1200px,但你可以通过 PICTURES["CONTAINER_WIDTH"] 设置覆盖此设置。

如果你不使用容器,你也可以将其设置为 None

文件类型

除非你仍然服务于 IE11 客户端,否则你应该可以仅提供 WebP。遗憾的是,AVIF(WebP 的继任者)尚未由 Pillow 支持

如果你正在为 IE11 服务,请将 JPEG 添加到列表中。但请注意,这可能会大幅增加你的存储需求。

像素密度

除非你真的很在乎你的图像在距离眼睛非常近的 UHD 手机上是否能保持清晰,否则你应该可以提供默认的 1x2x 密度。

异步图像处理

如果您已安装 Dramatiq 或 Celery,我们将默认使用异步图像处理。您需要工作进程来监听 pictures 队列。您可以通过 PICTURES["QUEUE_NAME"] 设置来覆盖队列名称。

您也可以通过 PICTURES["PROCESSOR"] 设置来覆盖处理器。默认处理器为 pictures.tasks.process_picture。它接受一个参数,即 PictureFileFile 实例。如果您需要进行一些自定义处理,可以使用此设置来覆盖处理器。

迁移

Django 不支持文件字段的迁移,但我们支持。您可以简单地自动创建迁移,并将 Django 的 AlterField 操作替换为 AlterPictureField。就是这样。

您可以通过查看我们测试应用的 示例 来了解它是如何工作的。

贡献

Django Rest Framework (DRF)

我们提供了一个只读的 PictureField,可用于在 DRF 序列化器中包含所有可用的图片尺寸。

from rest_framework import serializers
from pictures.contrib.rest_framework import PictureField

class PictureSerializer(serializers.Serializer):
    picture = PictureField()

通过向 DRF 字段提供 aspect_ratiosfile_types 参数,可以限制响应的宽高比和文件类型。

from rest_framework import serializers
from pictures.contrib.rest_framework import PictureField

class PictureSerializer(serializers.Serializer):
    picture = PictureField(aspect_ratios=["16/9"], file_types=["WEBP"])

您还可以向序列化器提供可选的 GET 参数,以指定要包含在响应中的宽高比和断点。参数以 fieldname_ 前缀开头,以避免与其他字段冲突。

curl http://localhost:8000/api/path/?picture_ratio=16%2F9&picture_m=6&picture_l=4
# %2F is the url encoded slash
{
  "other_fields": "…",
  "picture": {
    "url": "/path/to/image.jpg",
    "width": 800,
    "height": 800,
    "ratios": {
      "1/1": {
        "sources": {
          "image/webp": {
            "100": "/path/to/image/1/100w.webp",
            "200": "…"
          }
        },
        "media": "(min-width: 0px) and (max-width: 991px) 100vw, (min-width: 992px) and (max-width: 1199px) 33vw, 25vw"
      }
    }
  }
}

请注意,只有当您指定了断点时,才会包括 media 键。

Django 清理

PictureFieldDjango Cleanup 兼容,该工具会自动删除其文件和相应的 SimplePicture 文件。

项目详情


下载文件

下载您平台的文件。如果您不确定要选择哪个,请了解更多关于 安装软件包 的信息。

源分布

django_pictures-1.3.3.tar.gz (19.8 kB 查看哈希)

上传于 源码

构建分发

django_pictures-1.3.3-py3-none-any.whl (21.3 kB 查看哈希)

上传于 Python 3

由以下支持