Metadata-Version: 2.1
Name: django-pictures
Version: 1.0a6
Summary: Responsive cross-browser image library using modern codes like AVIF & WebP.
Keywords: pillow,Django,image,pictures,WebP,AVIF
Author-email: Johannes Maron <johannes@maron.family>
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python
Classifier: Environment :: Web Environment
Classifier: Topic :: Multimedia :: Graphics :: Graphics Conversion
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Framework :: Django
Classifier: Framework :: Django :: 3.2
Classifier: Framework :: Django :: 4.0
Requires-Dist: django
Requires-Dist: pillow
Requires-Dist: celery ; extra == "celery"
Requires-Dist: django-dramatiq ; extra == "dramatiq"
Requires-Dist: djangorestframework ; extra == "drf"
Requires-Dist: pytest ; extra == "test"
Requires-Dist: pytest-cov ; extra == "test"
Requires-Dist: pytest-django ; extra == "test"
Requires-Dist: redis ; extra == "test"
Project-URL: Changelog, https://github.com/codingjoe/django-pictures/releases
Project-URL: Project-URL, https://github.com/codingjoe/django-pictures
Provides-Extra: celery
Provides-Extra: dramatiq
Provides-Extra: drf
Provides-Extra: test

# django-pictures

Responsive cross-browser image library using modern codes like AVIF & WebP.

* responsive web images using the [picture](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture) tag
* native grid system support
* serve files with our without a CDN
* placeholders for local development
* migration support
* async image processing for Celery or Dramatiq

[![PyPi Version](https://img.shields.io/pypi/v/django-pictures.svg)](https://pypi.python.org/pypi/django-pictures/)
[![Test Coverage](https://codecov.io/gh/codingjoe/django-pictures/branch/main/graph/badge.svg)](https://codecov.io/gh/codingjoe/django-pictures)
[![GitHub License](https://img.shields.io/github/license/codingjoe/django-pictures)](https://raw.githubusercontent.com/codingjoe/django-pictures/master/LICENSE)

### Usage

```python
# 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")
```

```html
<!-- template.html -->
{% load pictures %}
{% picture profile.picture alt="Spiderman" loading="lazy" m=6 l=4 %}
```

The template above will render into:
```html
<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>
```

### Setup

```shell
python3 -m pip install django-pictures
```

```python
# settings.py
INSTALLED_APPS = [
    # ...
    'django_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],
}
```

If you have either Dramatiq or Celery installed, we will default to async
image processing. You will need workers to listen to the `pictures` queue.

#### Placeholders

This library comes with dynamically created placeholders to simplify local
development. To enable them, add the following to enable the
`PICTURES["USE_PLACEHOLDERS"]` setting and add the following URL configuration:

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

urlpatterns = [
    # ...
]

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

### Config

#### Breakpoints

You may define your own breakpoints, they should be identical to the ones used
in your css library. Simply override the `PICTURES["BREAKPOINTS"]` setting.

#### Grid columns

Grids are so common in web design, that they even made it into CSS.
We default to 12 columns, but you can override this setting, via the
`PICTURES["GRID_COLUMNS"]` setting.

#### Container width

Containers are commonly used to limit the maximum width of layouts,
to promote better readability on larger screens. We default to `1200px`,
but you can override this setting, via the `PICTURES["CONTAINER_WIDTH"]` setting.

You may also set it to `None`, should you not use a container.

#### File types

Unless you still services IE11 clients, you should be fine serving just
[WebP](https://caniuse.com/webp). Sadly, [AVIF](https://caniuse.com/avif)
(WebP's successor) is
[not yet supported by Pillow](https://github.com/python-pillow/Pillow/pull/5201).

#### Pixel densities

Unless you really care that your images hold of if you hold your UHD phone very
close to your eyeballs, you should be fine, serving at the default `1x` and `2x`
densities.


#### Async image processing

If you have either Dramatiq or Celery installed, we will default to async
image processing. You will need workers to listen to the `pictures` queue.
You can override the queue name, via the `PICTURES["QUEUE_NAME"]` setting.

### Migrations

Django doesn't support file field migrations, but we do.
You can simply auto create the migration and replace Django's
`AlterField` operation with `AlterPictureField`. That's it.

You can follow [the example][migration] in our test app, to see how it works.

[migration]: tests/testapp/migrations/0002_alter_profile_picture.py


## Contrib

### Django Rest Framework (DRF)

We do ship with a read-only `PictureField` that can be used to include all
available picture sizes in a DRF serializer.

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

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

