ΠΡΠΈΠ½Ρ ΡΠΎΠ½Π½Π°Ρ Π·Π°Π³ΡΡΠ·ΠΊΠ° ΡΠ°ΠΉΠ»ΠΎΠ² Π΄Π»Ρ Π°Π΄ΠΌΠΈΠ½ΠΈΡΡΡΠ°ΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ° Django.
- Python >= 3.9
- Django >= 3.2
- paper-admin >= 7.0
- variations
- ΠΠ°ΠΆΠ΄ΡΠΉ ΡΠ°ΠΉΠ» ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ ΡΠ²ΠΎΠ΅ΠΉ ΠΌΠΎΠ΄Π΅Π»ΡΡ. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Ρ
ΡΠ°Π½ΠΈΡΡ
Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΡΠ°ΠΉΠ»ΠΎΠΌ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ,
alt
Π΄Π»Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ. - ΠΠ°Π³ΡΡΠ·ΠΊΠ° ΡΠ°ΠΉΠ»ΠΎΠ² ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π°ΡΠΈΠ½Ρ ΡΠΎΠ½Π½ΠΎ ΠΈ Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ ΡΡΠ°Π·Ρ ΠΏΡΠΈ Π²ΡΠ±ΠΎΡΠ΅ ΡΠ°ΠΉΠ»Π° Π² ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ΅ Π°Π΄ΠΌΠΈΠ½ΠΈΡΡΡΠ°ΡΠΎΡΠ°.
- ΠΠΎΠ»Ρ ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌΡΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΎΠΉ
paper-uploads
, ΡΠ²Π»ΡΡΡΡΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΡΠΌΠΈ ΠΎΡOneToOneField
ΠΈ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ<input type="file">
. ΠΠ»Π°Π³ΠΎΠ΄Π°ΡΡ ΡΡΠΎΠΌΡ, ΠΏΡΠΈ ΠΎΡΠΈΠ±ΠΊΠ°Ρ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ ΡΠΎΡΠΌΡ ΠΏΡΠΈΠΊΡΠ΅ΠΏΠ»Π΅Π½Π½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ Π½Π΅ ΡΠ±ΡΠ°ΡΡΠ²Π°ΡΡΡΡ. - ΠΠ°Π³ΡΡΠΆΠ΅Π½Π½ΡΠ΅ ΠΊΠ°ΡΡΠΈΠ½ΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΠ΅Π·Π°ΡΡ Π½Π° ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ.
ΠΠ°ΠΆΠ΄Π°Ρ Π²Π°ΡΠΈΠ°ΡΠΈΡ Π³ΠΈΠ±ΠΊΠΎ Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΡΡΡ. ΠΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΡΠ°Π·ΠΌΠ΅ΡΡ,
ΠΊΠ°ΡΠ΅ΡΡΠ²ΠΎ ΡΠΆΠ°ΡΠΈΡ, ΡΠΎΡΠΌΠ°Ρ, Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅
pilkit-ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΡ, ΡΠ°ΡΠΏΠΎΠ·Π½Π°Π²Π°Π½ΠΈΠ΅ Π»ΠΈΡ ΠΈ ΠΏΡΠΎΡΠ΅Π΅.
Π‘ΠΌ. variations. - Π‘ΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌ Ρ django-storages.
- ΠΠΏΡΠΈΠΎΠ½Π°Π»ΡΠ½Π°Ρ ΠΈΠ½ΡΠ΅Π³ΡΠ°ΡΠΈΡ Ρ django-rq Π΄Π»Ρ ΠΎΡΠ»ΠΎΠΆΠ΅Π½Π½ΠΎΠΉ Π½Π°ΡΠ΅Π·ΠΊΠΈ ΠΊΠ°ΡΡΠΈΠ½ΠΎΠΊ Π½Π° Π²Π°ΡΠΈΠ°ΡΠΈΠΈ.
- ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΡΠ°ΠΉΠ»ΠΎΠ². Π ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ, Π³Π°Π»Π΅ΡΠ΅ΠΉ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΡ ΡΠΎΡΡΠΈΡΠΎΠ²ΠΊΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ².
- Installation
- ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅
- FileField ΠΈ ImageField
- SVGFileField
- ΠΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ
- Management ΠΊΠΎΠΌΠ°Π½Π΄Ρ
- Settings
Install paper-uploads
:
pip install paper-uploads[full]
Add paper_uploads
to INSTALLED_APPS
in settings.py
:
INSTALLED_APPS = [
# ...
"paper_uploads",
# ...
]
Configure paper-uploads
in django's settings.py
:
PAPER_UPLOADS = {
"VARIATION_DEFAULTS": {
"jpeg": dict(
quality=80,
progressive=True,
),
"webp": dict(
quality=75,
)
}
}
# Add JS translations
PAPER_LOCALE_PACKAGES = [
"paper_admin",
"paper_uploads",
"django.contrib.admin",
]
Π ΡΠΎΡΡΠ°Π² Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π²Ρ
ΠΎΠ΄ΠΈΡ Π΄Π²Π° ΠΏΠΎΠ»Ρ β FileField
ΠΈ ImageField
β
ΠΈ ΠΌΠΎΠ΄Π΅Π»Ρ Collection
, ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½Π½Π°Ρ Π΄Π»Ρ Π³ΡΡΠΏΠΏΠΈΡΠΎΠ²ΠΊΠΈ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΡΡ
ΡΠ°ΠΉΠ»ΠΎΠ²
Ρ ΡΠ΅Π»ΡΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ, ΠΊ ΠΏΡΠΈΠΌΠ΅ΡΡ, ΡΠΎΡΠΎΠ³Π°Π»Π΅ΡΠ΅ΠΉ.
Π‘ ΠΏΡΠΈΠΌΠ΅ΡΠ°ΠΌΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΎΠ·Π½Π°ΠΊΠΎΠΌΠΈΡΡΡΡ Π·Π΄Π΅ΡΡ.
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import FileField, ImageField
class Page(models.Model):
file = FileField(
_("file"),
blank=True
)
image = ImageField(
_("image"),
blank=True
)
ΠΡΠΈ ΠΏΠΎΠ»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π΄Π»Ρ ΡΠ΅Ρ ΠΆΠ΅ ΡΠ΅Π»Π΅ΠΉ, ΡΡΠΎ ΠΈ ΠΎΠ΄Π½ΠΎΠΈΠΌΡΠ½Π½ΡΠ΅ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠ΅ ΠΏΠΎΠ»Ρ Django β Π΄Π»Ρ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΡΠ°ΠΉΠ»ΠΎΠ² ΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ β Π½ΠΎ ΠΈΠΌΠ΅ΡΡ ΡΡΠ΄ ΡΡΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΡ ΠΎΡΠ»ΠΈΡΠΈΠΉ.
ΠΠ»Π°Π²Π½ΠΎΠ΅ ΠΎΡΠ»ΠΈΡΠΈΠ΅ Π·Π°ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΏΠΎΠ»Ρ FileField
ΠΈ ImageField
ΡΠ²Π»ΡΡΡΡΡ
ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΡΠΌΠΈ ΠΎΡ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠ³ΠΎ OneToOneField
. Π‘ΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΡΠ΅ ΡΠ°ΠΉΠ»Ρ
ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Ρ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°ΠΌΠΈ ΠΏΠΎΠ»Π½ΠΎΡΠ΅Π½Π½ΡΡ
ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ.
Π€Π°ΠΉΠ»Ρ, Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΡΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΠΎΠ»Π΅ΠΉ FileField
ΠΈ ImageField
, Ρ
ΡΠ°Π½ΡΡΡΡ Π²
ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°Ρ
ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ UploadedFile
ΠΈ UploadedImage
ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ.
Π ΡΠ»Π΅Π΄ΡΡΡΠΈΡ ΡΠ°Π±Π»ΠΈΡΠ°Ρ ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»Π΅Π½Ρ ΠΎΠ±ΡΠΈΠ΅ ΠΏΠΎΠ»Ρ ΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΎΠ±Π΅ΠΈΡ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ:
ΠΠΎΠ»Π΅ | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ |
---|---|
resource_name | ΠΠΌΡ ΡΠ°ΠΉΠ»Π° Π±Π΅Π· ΠΏΡΡΠΈ, ΡΡΡΡΠΈΠΊΡΠ° ΠΈ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ. ΠΡΠΈΠΌΠ΅Ρ: report2020 . |
extension | Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»Π° Π² Π½ΠΈΠΆΠ½Π΅ΠΌ ΡΠ΅Π³ΠΈΡΡΡΠ΅ Π±Π΅Π· ΡΠΎΡΠΊΠΈ. ΠΡΠΈΠΌΠ΅Ρ: pdf . |
size | Π Π°Π·ΠΌΠ΅Ρ ΡΠ°ΠΉΠ»Π° Π² Π±Π°ΠΉΡΠ°Ρ . |
checksum | ΠΠΎΠ½ΡΡΠΎΠ»ΡΠ½Π°Ρ ΡΡΠΌΠΌΠ° ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°Π½ΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΡΠ°ΠΉΠ»Π°. |
uploaded_at | ΠΠ°ΡΠ° ΠΈ Π²ΡΠ΅ΠΌΡ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΡΠ°ΠΉΠ»Π°. |
created_at | ΠΠ°ΡΠ° ΠΈ Π²ΡΠ΅ΠΌΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ. |
modified_at | ΠΠ°ΡΠ° ΠΈ Π²ΡΠ΅ΠΌΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° ΠΌΠΎΠ΄Π΅Π»ΠΈ. |
Π‘Π²ΠΎΠΉΡΡΠ²ΠΎ | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ |
---|---|
name | ΠΠΎΠ»Π½ΠΎΠ΅ ΠΈΠΌΡ ΡΠ°ΠΉΠ»Π°. ΠΡΠΈΠΌΠ΅Ρ: files/report2020_19sc2Kj.pdf . |
url | URL-Π°Π΄ΡΠ΅Ρ ΡΠ°ΠΉΠ»Π°. ΠΡΠΈΠΌΠ΅Ρ: /media/files/report2020_19sc2Kj.pdf . |
path | ΠΠ±ΡΠΎΠ»ΡΡΠ½ΡΠΉ ΠΏΡΡΡ ΠΊ ΡΠ°ΠΉΠ»Ρ. ΠΡΠΈΠΌΠ΅Ρ: /home/www/django/media/files/report2020_19sc2Kj.pdf . |
ΠΠΈΠΆΠ΅ ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»Π΅Π½Ρ ΠΏΠΎΠ»Ρ ΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π°, ΡΠΏΠ΅ΡΠΈΡΠΈΡΠ½ΡΠ΅ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ.
Π‘ΠΏΠ΅ΡΠΈΡΠΈΡΠ½ΡΠ΅ ΠΏΠΎΠ»Ρ UploadedFile
:
ΠΠΎΠ»Π΅ | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ |
---|---|
display_name | Π£Π΄ΠΎΠ±ΠΎΡΠΈΡΠ°Π΅ΠΌΠΎΠ΅ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»Π° Π΄Π»Ρ Π²ΡΠ²ΠΎΠ΄Π° Π½Π° ΡΠ°ΠΉΡΠ΅. ΠΠ°ΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ Π² Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠΌ ΠΎΠΊΠ½Π΅ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠ°ΠΉΠ»Π°. ΠΡΠΈΠΌΠ΅Ρ: Annual report 2020 . |
Π‘ΠΏΠ΅ΡΠΈΡΠΈΡΠ½ΡΠ΅ ΠΏΠΎΠ»Ρ UploadedImage
:
ΠΠΎΠ»Π΅ | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ |
---|---|
title | ΠΠ°Π·Π²Π°Π½ΠΈΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡΠ°Π²ΠΈΡΡ Π² Π°ΡΡΠΈΠ±ΡΡ title ΡΡΠ³Π° <img> . |
description | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡΠ°Π²ΠΈΡΡ Π² Π°ΡΡΠΈΠ±ΡΡ alt ΡΡΠ³Π° <img> . |
width | Π¨ΠΈΡΠΈΠ½Π° Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ. |
height | ΠΡΡΠΎΡΠ° Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ. |
ratio | ΠΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅ ΡΠΈΡΠΈΠ½Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΊ Π²ΡΡΠΎΡΠ΅ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ Decimal . |
hw_ratio | ΠΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅ Π²ΡΡΠΎΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΊ ΡΠΈΡΠΈΠ½Π΅ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ Decimal . |
srcset | Π‘ΡΡΠΎΠΊΠ° ΡΠΎΡΠΌΠ°ΡΠ° [URL] [WIDTH]w . |
ΠΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΠΏΠΎΠ»Π΅ΠΉ Π·Π°ΠΏΠΎΠ»Π½ΡΡΡΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΠΏΡΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠ΅ ΡΠ°ΠΉΠ»Π° ΠΈ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½Ρ
ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ ΡΡΠ΅Π½ΠΈΡ. ΠΠΎ ΡΠ°ΠΊΠΈΠ΅ ΠΏΠΎΠ»Ρ, ΠΊΠ°ΠΊ display_name
ΠΈΠ»ΠΈ title
, Π·Π°ΠΏΠΎΠ»Π½ΡΡΡΡΡ
ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Π΅ΠΌ Π² Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠΌ ΠΎΠΊΠ½Π΅ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠ°ΠΉΠ»Π°:
ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π²ΡΠ΅ ΠΏΠΎΠ»Ρ paper-uploads
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ Π΅Π΄ΠΈΠ½ΡΠΉ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ°,
ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌΡΠΉ Π½Π°ΡΡΡΠΎΠΉΠΊΠ°ΠΌΠΈ STORAGE
ΠΈ STORAGE_OPTIONS
:
# settings.py
PAPER_UPLOADS = {
"STORAGE": "django.core.files.storage.FileSystemStorage",
"STORAGE_OPTIONS": {},
# ...
}
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΡ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° Π΄Π»Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»Ρ:
from django.db import models
from django.core.files.storage import FileSystemStorage
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import FileField
class Page(models.Model):
report = FileField(
_("report"),
blank=True,
storage=FileSystemStorage(location="uploads/"),
upload_to="reports/%Y/%m"
)
ΠΡΠ΅ ΠΏΠΎΠ»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ Π΅Π΄ΠΈΠ½ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ, ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ Π² Π½Π°ΡΡΡΠΎΠΉΠΊΠ°Ρ
FILES_UPLOAD_TO
ΠΈ IMAGES_UPLOAD_TO
:
# settings.py
PAPER_UPLOADS = {
# ...
"FILES_UPLOAD_TO": "files/%Y/%m/%d",
"IMAGES_UPLOAD_TO": "images/%Y/%m/%d",
# ...
}
ΠΠ»Ρ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ»Ρ ΠΊΠ°ΡΠ°Π»ΠΎΠ³ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ΅ ΠΏΠΎΠ»Ρ upload_to
.
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΡΠΎΡΠΌΠ°ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ strftime()
, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π±ΡΠ΄Π΅Ρ Π·Π°ΠΌΠ΅Π½Π΅Π½ΠΎ Π½Π°
Π΄Π°ΡΡ/Π²ΡΠ΅ΠΌΡ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° (ΠΈ Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌΡΠ΅ ΡΠ°ΠΉΠ»Ρ Π½Π΅ Π·Π°ΠΏΠΎΠ»Π½ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΊΠ°ΡΠ°Π»ΠΎΠ³).
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import FileField
class Page(models.Model):
report = FileField(
_("report"),
blank=True,
upload_to="pdf/reports/%Y"
)
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΡΡΠΎ Π² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ upload_to
Π½Π΅Π»ΡΠ·Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π²ΡΠ·ΡΠ²Π°Π΅ΠΌΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ.
ΠΡΠ»ΠΈ Π²Π°ΠΌ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΊΠ°ΡΠ°Π»ΠΎΠ³Π° ΠΈΠ»ΠΈ ΠΈΠΌΠ΅Π½ΠΈ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°,
ΡΠΎΠ·Π΄Π°ΠΉΡΠ΅ proxy-ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π»ΠΈΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ generate_filename()
:
import os
import datetime
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import FileField, UploadedFile
class UploadedFileProxy(UploadedFile):
class Meta:
proxy = True
def generate_filename(self, filename: str) -> str:
_, ext = os.path.splitext(filename)
filename = "proxy-files/file-%Y-%m-%d_%H%M%S{}".format(ext)
filename = datetime.datetime.now().strftime(filename)
storage = self.get_file_storage()
return storage.generate_filename(filename)
class Page(models.Model):
file = FileField(
_("file"),
to=UploadedFileProxy,
blank=True,
)
ΠΠ° Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌΡΠ΅ ΡΠ°ΠΉΠ»Ρ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π»ΠΎΠΆΠΈΡΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π²Π°Π»ΠΈΠ΄Π°ΡΠΎΡΠΎΠ².
ΠΠΎΠ΄ΡΠ»Ρ paper-uploads.validators
ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΊΠ»Π°ΡΡΡ Π΄Π»Ρ Π²Π°Π»ΠΈΠ΄Π°ΡΠΈΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²:
-
MaxSizeValidator
- Π·Π°Π΄Π°Π΅Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΠΎ Π΄ΠΎΠΏΡΡΡΠΈΠΌΡΠΉ ΡΠ°Π·ΠΌΠ΅Ρ ΡΠ°ΠΉΠ»Π°.
ΠΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΡΠ°Π·ΠΌΠ΅Ρ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΠΊΠ°ΠΊ Π² Π²ΠΈΠ΄Π΅ ΡΠΈΡΠ»Π° (Π² Π±Π°ΠΉΡΠ°Ρ ), ΡΠ°ΠΊ ΠΈ Π² Π²ΠΈΠ΄Π΅ ΡΡΡΠΎΠΊΠΈ.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ:4 * 10 ** 6
,4mb
,4MB
,4M
. -
ExtensionValidator
- Π·Π°Π΄Π°Π΅Ρ Π΄ΠΎΠΏΡΡΡΠΈΠΌΡΠ΅ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ². -
MimeTypeValidator
- Π·Π°Π΄Π°Π΅Ρ Π΄ΠΎΠΏΡΡΡΠΈΠΌΡΠ΅ MIME-ΡΠΈΠΏΡ ΡΠ°ΠΉΠ»ΠΎΠ². -
ImageMinSizeValidator
- ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΡΠ°Π·ΠΌΠ΅Ρ Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ. -
ImageMaxSizeValidator
- ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΡΠ°Π·ΠΌΠ΅Ρ Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ.
ΠΡΠΈΠΌΠ΅Ρ:
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import FileField
from paper_uploads.validators import ExtensionValidator, MaxSizeValidator
class Page(models.Model):
report = FileField(
_("file"),
blank=True,
validators=[
ExtensionValidator([".pdf", ".doc", ".docx"]),
MaxSizeValidator("10MB")
]
)
ΠΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ, Π½Π°Π»ΠΎΠΆΠ΅Π½Π½ΡΠ΅ ΡΡΠΈΠΌΠΈ Π²Π°Π»ΠΈΠ΄Π°ΡΠΎΡΠ°ΠΌΠΈ, ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡΡΡ Π² Π²ΠΈΠ΄ΠΆΠ΅ΡΠ΅:
from paper_uploads.models import *
report = UploadedFile()
report.set_owner_field(Page, "report")
report.attach("/tmp/file.doc")
report.save()
page = Page.objects.create(
report=report
)
Π ΠΌΠ΅ΡΠΎΠ΄ set_owner_field()
ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈ ΠΈΠΌΡ ΠΏΠΎΠ»Ρ ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π² ΠΊΠΎΡΠΎΡΠΎΠ΅ Π±ΡΠ΄Π΅Ρ
ΡΠΎΡ
ΡΠ°Π½Π΅Π½ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΡΠ°ΠΉΠ»Π°. ΠΡΠΈ Π΄Π°Π½Π½ΡΠ΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡ Π΄Π»Ρ Π²ΡΡΠ²Π»Π΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅
Π½ΠΈΠ³Π΄Π΅ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ.
ΠΠ΅ΡΠΎΠ΄ attach()
ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎΠ΅ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»Π° ΠΈ Π·Π°ΠΏΠΎΠ»Π½ΡΠ΅Ρ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ
Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠΌΠΈ Π΄Π°Π½Π½ΡΠΌΠΈ. Π ΠΌΠ΅ΡΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΊΠ°ΠΊ ΠΏΡΡΡ ΠΊ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΌΡ ΡΠ°ΠΉΠ»Ρ, ΡΠ°ΠΊ
ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ.
ImageField
ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ Π΄Π»Ρ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ.
ΠΠ°ΡΠΈΠ°ΡΠΈΡ - ΡΡΠΎ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅, ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΠΎΠ΅ ΠΈΠ· ΠΈΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎ Π·Π°ΡΠ°Π½Π΅Π΅ ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π½ΡΠΌ ΠΏΡΠ°Π²ΠΈΠ»Π°ΠΌ.
ΠΠ»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° variations.
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import *
class Page(models.Model):
image = ImageField(
_("image"),
blank=True,
variations=dict(
desktop=dict(
size=(800, 0),
clip=False,
),
mobile=dict(
size=(600, 0),
clip=False,
),
)
)
Π ΡΠ°ΠΉΠ»Π°ΠΌ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ ΡΠ΅ΡΠ΅Π· ΠΌΠΎΠ΄Π΅Π»Ρ UploadedImage
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΈΡ
ΠΈΠΌΠ΅Π½Π°:
print(page.image.desktop.url)
# /media/images/2022/02/21/sample.desktop.jpg
Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ² Π²Π°ΡΠΈΠ°ΡΠΈΠΉ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ Π² ΠΌΠΎΠΌΠ΅Π½Ρ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π½Π° ΡΠ΅ΡΠ²Π΅Ρ. ΠΠΎΡΡΠΎΠΌΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π½Π°ΡΡΡΠΎΠ΅ΠΊ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ Π½Π΅ ΠΎΠΊΠ°ΠΆΠ΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΎΠ³ΠΎ ΡΡΡΠ΅ΠΊΡΠ° Π½Π° ΡΠΆΠ΅ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΡΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ.
ΠΠ»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠ°ΠΉΠ»Ρ Π΄Π»Ρ Π½ΠΎΠ²ΡΡ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ (Π»ΠΈΠ±ΠΎ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΠΈΡΠ°ΡΡ ΡΡΡΠ΅ΡΡΠ²ΡΡΡΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ) ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΡΡΠΏΠΈΡΡ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· Π½ΠΈΠΆΠ΅ ΠΎΠΏΠΈΡΠ°Π½Π½ΡΡ ΡΠΏΠΎΡΠΎΠ±ΠΎΠ².
-
ΠΡΠ·Π²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄
recut()
:page.image.recut()
ΠΡΠΈ Π²ΡΠ·ΠΎΠ²Π΅ ΡΡΠΎΠ³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π° Π²ΡΠ΅ ΡΠ°ΠΉΠ»Ρ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ Π΄Π»Ρ ΡΠ΅ΠΊΡΡΠ΅Π³ΠΎ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° ΡΠΎΠ·Π΄Π°ΡΡΡΡ Π·Π°Π½ΠΎΠ²ΠΎ.
ΠΠΎΠΆΠ½ΠΎ ΡΠ²Π½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΠΈΠΌΠ΅Π½Π° Π²Π°ΡΠΈΠ°ΡΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΠΈΡΠ°ΡΡ:page.image_group.recut(["desktop", "mobile"])
-
ΠΡΠΏΠΎΠ»Π½ΠΈΡΡ management-ΠΊΠΎΠΌΠ°Π½Π΄Ρ
recreate_variations
:python3 manage.py recreate_variations app.page \ --field image --variations desktop mobile
ΠΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π° ΡΠ³Π΅Π½Π΅ΡΠΈΡΡΠ΅Ρ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ Π΄Π»Ρ Π²ΡΠ΅Ρ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ.
ΠΠΎΠΏΡΡΡΠΈΠΌ, Ρ Π½Π°Ρ Π΅ΡΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π½ΡΠΆΠ½ΠΎ ΠΎΡΠΎΠ±ΡΠ°Π·ΠΈΡΡ Π² ΡΡΠ΅Ρ
Π²Π°ΡΠΈΠ°Π½ΡΠ°Ρ
: desktop
, tablet
ΠΈ mobile
. ΠΡΠ»ΠΈ ΠΌΡ Ρ
ΠΎΡΠΈΠΌ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ
Π΄ΠΈΡΠΏΠ»Π΅ΠΈ Retina, Π½Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π΅ΡΡ ΡΡΠΈ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ Π΄Π»Ρ ΡΠ°Π·ΠΌΠ΅ΡΠ° 2x
.
ΠΡΠ»ΠΈ ΠΌΡ ΡΠ°ΠΊΠΆΠ΅ Ρ
ΠΎΡΠΈΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΎΡΠΌΠ°Ρ WebP
(ΡΠΎΡ
ΡΠ°Π½ΠΈΠ² ΠΈΡΡ
ΠΎΠ΄Π½ΡΠΉ ΡΠΎΡΠΌΠ°Ρ
Π΄Π»Ρ ΠΎΠ±ΡΠ°ΡΠ½ΠΎΠΉ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΠΎΡΡΠΈ), ΡΠΎ ΠΎΠ±ΡΠ΅Π΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ Π΄ΠΎΡΡΠΈΠ³Π°Π΅Ρ 12.
ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ Retina-Π²Π°ΡΠΈΠ°ΡΠΈΠΈ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ ΠΎΡ ΠΎΠ±ΡΡΠ½ΡΡ
ΡΠΎΠ»ΡΠΊΠΎ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½Π½ΡΠΌ
Π½Π° ΠΏΠΎΡΡΠΎΡΠ½Π½ΡΠΉ ΠΊΠΎΡΡΡΠΈΡΠΈΠ΅Π½Ρ ΡΠ°Π·ΠΌΠ΅ΡΠΎΠΌ, Π° WebP
-Π²Π°ΡΠΈΠ°ΡΠΈΠΈ β Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ
ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ° format = "webp"
, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΡΡΠΈ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ
Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ. ΠΡΠΎ ΠΈ Π΅ΡΡΡ Π²Π΅ΡΡΠΈΠΈ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ.
ΠΠ΅ΡΠ΅ΡΠ΅Π½Ρ Π²Π΅ΡΡΠΈΠΉ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½ΡΠΆΠ½ΠΎ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ, ΡΠΊΠ°Π·ΡΠ²Π°ΡΡΡΡ Π² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ΅
Π²Π°ΡΠΈΠ°ΡΠΈΠΈ versions
. ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ:
webp
, 2x
, 3x
, 4x
.
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import *
class Page(models.Model):
image = ImageField(
_("image"),
blank=True,
variations=dict(
desktop=dict(
# ...
versions={"webp", "2x", "3x"}
)
)
)
ΠΡΠΈΠ²Π΅Π΄Π΅Π½Π½ΡΠΉ Π²ΡΡΠ΅ ΠΊΠΎΠ΄ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ:
-
desktop
- ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½Π°Ρ Π²Π°ΡΠΈΠ°ΡΠΈΡ -
desktop_webp
-WebP
-Π²Π΅ΡΡΠΈΡ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΠΎΠΉ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ -
desktop_2x
- Retina 2x -
desktop_webp_2x
-WebP
-Π²Π΅ΡΡΠΈΡ Retina 2x -
desktop_3x
- Retina 3x -
desktop_webp_3x
-WebP
-Π²Π΅ΡΡΠΈΡ Retina 3x
NOTE: Retina-ΡΡΡΡΠΈΠΊΡ Π²ΡΠ΅Π³Π΄Π° ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΏΠΎΡΠ»Π΅ ΡΡΡΡΠΈΠΊΡΠ° webp
, Π΅ΡΠ»ΠΈ
ΠΎΠ½ Π΅ΡΡΡ.
ΠΡΠ»ΠΈ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΠΊΠ°ΠΊΠΈΠ΅-ΡΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΠΎΠΉ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ, ΡΠΎ ΠΏΡΠΈΠ΄ΡΡΡΡ ΠΎΠ±ΡΡΠ²Π»ΡΡΡ Π²Π°ΡΠΈΠ°ΡΠΈΡ ΡΠ²Π½ΠΎ:
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import *
class Page(models.Model):
image = ImageField(
_('image'),
blank=True,
variations=dict(
desktop=dict(
size=(800, 600),
versions={'webp', '2x', '3x'}
),
desktop_2x=dict(
size=(1600, 1200),
jpeg=dict(
quality=72
)
)
)
)
ΠΡΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠ΅ Π±ΠΎΠ»ΡΡΠΎΠ³ΠΎ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΠΏΡΠΎΡΠ΅ΡΡ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ ΠΌΠΎΠΆΠ΅Ρ Π·Π°Π½ΠΈΠΌΠ°ΡΡ Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎΠ΅ Π²ΡΠ΅ΠΌΡ. ΠΡΡ ΡΠ°Π±ΠΎΡΡ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ½Π΅ΡΡΠΈ Π² ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΏΡΠΎΡΠ΅ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ django-rq:
pip install django-rq
# settings.py
PAPER_UPLOADS = {
"RQ_ENABLED": True,
"RQ_QUEUE_NAME": "default",
# ...
}
Π’Π΅ΠΏΠ΅ΡΡ ΠΏΡΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ, Π² ΠΎΡΠ΅ΡΠ΅Π΄Ρ ΠΏΠΎΠ΄ ΠΈΠΌΠ΅Π½Π΅ΠΌ default
Π±ΡΠ΄Π΅Ρ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡΡΡ
Π·Π°Π΄Π°ΡΠ°, ΠΊΠΎΡΠΎΡΠ°Ρ ΡΠΎΠ·Π΄Π°ΡΡ Π²ΡΠ΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡΠ΅ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ.
ΠΠΎΠ»Π΅ SVGFileField
ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½ΠΎ Π΄Π»Ρ Π·Π°Π³ΡΡΠ·ΠΊΠΈ SVG-ΡΠ°ΠΉΠ»ΠΎΠ². ΠΠ½ΠΎ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½ΠΎ FileField
,
Π½ΠΎ ΡΠ²ΡΠ·Π°Π½Π½Π°Ρ Ρ Π½ΠΈΠΌ ΠΌΠΎΠ΄Π΅Π»Ρ UploadedSVGFile
Π²ΠΊΠ»ΡΡΠ°Π΅Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΡ
ΠΏΠΎΠ»Π΅ΠΉ:
ΠΠΎΠ»Π΅ | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ |
---|---|
width | Π¨ΠΈΡΠΈΠ½Π° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ Decimal . ΠΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π²Π΅ΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΠΌ ΡΠΈΡΠ»ΠΎΠΌ. |
height | ΠΡΡΠΎΡΠ° ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ Decimal . ΠΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π²Π΅ΡΠ΅ΡΡΠ²Π΅Π½Π½ΡΠΌ ΡΠΈΡΠ»ΠΎΠΌ. |
title | ΠΠ°Π·Π²Π°Π½ΠΈΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡΠ°Π²ΠΈΡΡ Π² Π°ΡΡΠΈΠ±ΡΡ title ΡΡΠ³Π° <img> . |
description | ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡΠ°Π²ΠΈΡΡ Π² Π°ΡΡΠΈΠ±ΡΡ alt ΡΡΠ³Π° <img> . |
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import SVGFileField
class Page(models.Model):
svg = SVGFileField(
_("svg"),
blank=True
)
ΠΠΎΠ»Π»Π΅ΠΊΡΠΈΡ β ΡΡΠΎ ΠΌΠΎΠ΄Π΅Π»Ρ, Π³ΡΡΠΏΠΏΠΈΡΡΡΡΠ°Ρ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΡ Π΄ΡΡΠ³ΠΈΡ ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ (ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ). Π ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ, Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ΡΠΎΡΠΎΠ³Π°Π»Π΅ΡΠ΅Ρ ΠΈΠ»ΠΈ ΡΠΏΠΈΡΠΎΠΊ ΡΠ°ΠΉΠ»ΠΎΠ².
ΠΠ»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠ±ΡΡΠ²ΠΈΡΡ ΠΊΠ»Π°ΡΡ, ΡΠ½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½Π½ΡΠΉ ΠΎΡ Collection
ΠΈ ΡΠΊΠ°Π·Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠ³ΡΡ Π²Ρ
ΠΎΠ΄ΠΈΡΡ Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΏΡΠ΅Π²Π΄ΠΎ-ΠΏΠΎΠ»Ρ
CollectionItem
:
from django.db import models
from paper_uploads.models import *
# Collection model
class PageFiles(Collection):
svg = CollectionItem(SVGItem)
image = CollectionItem(ImageItem)
file = CollectionItem(FileItem)
class Page(models.Model):
files = CollectionField(PageFiles)
ΠΠ»Π°ΡΡ Collection
ΠΎΠ±Π»Π°Π΄Π°Π΅Ρ ΠΎΡΠΎΠ±Π΅Π½Π½ΡΠΌ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎΠΌ: Π»ΡΠ±ΠΎΠΉ Π΄ΠΎΡΠ΅ΡΠ½ΠΈΠΉ ΠΊΠ»Π°ΡΡ, ΡΠ½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°Π½Π½ΡΠΉ
ΠΎΡ Collection
, ΡΠ²Π»ΡΠ΅ΡΡΡ proxy-ΠΌΠΎΠ΄Π΅Π»ΡΡ Π΄Π»Ρ Collection
.
Π Π±ΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²Π΅ ΡΠ»ΡΡΠ°Π΅Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ Π΄ΡΡΠ³ ΠΎΡ Π΄ΡΡΠ³Π° ΡΠΎΠ»ΡΠΊΠΎ Π½Π°Π±ΠΎΡΠΎΠΌ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠ³ΡΡ Π²Ρ ΠΎΠ΄ΠΈΡΡ Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΡ. ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ proxy-ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠ°Π΅Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π° ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΡΡ ΡΠ°Π±Π»ΠΈΡ Π² ΠΠ.
ΠΡΠ»ΠΈ ΠΆΠ΅ Π΄Π»Ρ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠ° ΠΎΡΠ΄Π΅Π»ΡΠ½Π°Ρ ΡΠ°Π±Π»ΠΈΡΠ° (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ Π²Ρ ΡΠ΅ΡΠΈΠ»ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ
Π² Π½Π΅Ρ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΠΎΠ»Π΅), ΡΠΎ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ²Π½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΠ²ΠΎΠΉΡΡΠ²ΠΎ Meta.proxy
Π² Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ False
:
from django.db import models
from paper_uploads.models import *
class CustomCollection(Collection):
name = models.CharField("name", max_length=128, blank=True)
file = CollectionItem(FileItem)
class Meta:
proxy = False
ΠΡΠ΅Π²Π΄ΠΎ-ΠΏΠΎΠ»Π΅ CollectionItem
ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠ΅Ρ ΠΌΠΎΠ΄Π΅Π»Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΠΏΠΎΠ΄ Π·Π°Π΄Π°Π½Π½ΡΠΌ ΠΈΠΌΠ΅Π½Π΅ΠΌ.
from paper_uploads.models import *
class PageFiles(Collection):
svg = CollectionItem(SVGItem)
image = CollectionItem(ImageItem)
file = CollectionItem(FileItem)
Π ΠΏΡΠΈΠ²Π΅Π΄ΡΠ½Π½ΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅, ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΡ PageFiles
ΠΌΠΎΠΆΠ΅Ρ Π²ΠΊΠ»ΡΡΠ°ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΡΡΠ΅Ρ
ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ:
SVGItem
, ImageItem
ΠΈ FileItem
.
ΠΠΎΡΡΠ΄ΠΎΠΊ ΠΎΠ±ΡΡΠ²Π»Π΅Π½ΠΈΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ Π²Π°ΠΆΠ΅Π½: ΠΏΠ΅ΡΠ²ΡΠΉ ΠΊΠ»Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΡΠ΅ΠΉ ΠΌΠ΅ΡΠΎΠ΄ accept()
Π²Π΅ΡΠ½Π΅Ρ True
, ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡ ΠΌΠΎΠ΄Π΅Π»Ρ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°. ΠΠΎ ΡΡΠΎΠΉ ΠΏΡΠΈΡΠΈΠ½Π΅ FileItem
Π΄ΠΎΠ»ΠΆΠ΅Π½
ΡΠΊΠ°Π·ΡΠ²Π°ΡΡΡΡ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΌ, Ρ.ΠΊ. ΠΎΠ½ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π»ΡΠ±ΡΠ΅ ΡΠ°ΠΉΠ»Ρ.
ΠΠΎΠ»ΡΡΠΈΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π½ΠΎΠ³ΠΎ ΡΠΈΠΏΠ° ΠΌΠΎΠΆΠ½ΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° get_items()
:
for item in page.files.get_items("image"):
# ...
Π ΡΠΎΡΡΠ°Π² Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π²Ρ ΠΎΠ΄ΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ²:
-
ImageItem
ΠΠ»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΡ Π½Π°ΡΠ΅Π·ΠΊΠΈ Π½Π° Π²Π°ΡΠΈΠ°ΡΠΈΠΈ. ΠΠΎΠΏΡΡΠΊΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ΅ ΡΠ°ΠΉΠ»Ρ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡΠΊΡΡΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Pillow. -
SVGItem
ΠΠ»Ρ Ρ ΡΠ°Π½Π΅Π½ΠΈΡ SVG ΠΈΠΊΠΎΠ½ΠΎΠΊ. -
FileItem
ΠΠΎΠΆΠ΅Ρ Ρ ΡΠ°Π½ΠΈΡΡ Π»ΡΠ±ΠΎΠΉ ΡΠ°ΠΉΠ».
ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ ΡΠΎΡ ΠΆΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ°,
ΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΏΠΎΠ»ΡΠΌΠΈ FileField
ΠΈ ImageField
.
ΠΠ°ΡΠ°Π»ΠΎΠ³ΠΈ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΡΠ°ΠΉΠ»ΠΎΠ² Π΄Π»Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΉ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡΡΡ Π² Π½Π°ΡΡΡΠΎΠΉΠΊΠ°Ρ
COLLECTION_FILES_UPLOAD_TO
ΠΈ COLLECTION_IMAGES_UPLOAD_TO
:
# settings.py
PAPER_UPLOADS = {
# ...
"COLLECTION_FILES_UPLOAD_TO": "collections/files/%Y/%m/%d",
"COLLECTION_IMAGES_UPLOAD_TO": "collections/images/%Y/%m/%d",
# ...
}
ΠΠ»Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎ Π²Π·ΡΡΠΎΠ³ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ Ρ
ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° ΠΈ ΠΊΠ°ΡΠ°Π»ΠΎΠ³ Π·Π°Π³ΡΡΠ·ΠΊΠΈ
ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ΅ options
ΠΏΡΠ΅Π²Π΄ΠΎ-ΠΏΠΎΠ»Ρ CollectionItem
:
from django.core.files.storage import FileSystemStorage
from paper_uploads.models import *
class PageFiles(Collection):
image = CollectionItem(ImageItem, options={
"storage": FileSystemStorage(location="uploads/"),
"upload_to": "gallery",
})
ΠΠ°ΠΊ Π² ΡΠ»ΡΡΠ°Π΅ Ρ FileField
ΠΈ ImageField
, Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ΠΌ upload_to
Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ Π²ΡΡΡΡΠΏΠ°ΡΡ
Π²ΡΠ·ΡΠ²Π°Π΅ΠΌΡΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ.
ΠΡΠ»ΠΈ Π²Π°ΠΌ ΡΡΠ΅Π±ΡΠ΅ΡΡΡ Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ ΠΊΠ°ΡΠ°Π»ΠΎΠ³Π° ΠΈΠ»ΠΈ ΠΈΠΌΠ΅Π½ΠΈ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°,
ΡΠΎΠ·Π΄Π°ΠΉΡΠ΅ proxy-ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π»ΠΈΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ generate_filename()
:
import os
import datetime
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import *
class ProxyImageItem(ImageItem):
class Meta:
proxy = True
def generate_filename(self, filename: str) -> str:
_, ext = os.path.splitext(filename)
filename = "gallery/image-%Y-%m-%d_%H%M%S{}".format(ext)
filename = datetime.datetime.now().strftime(filename)
storage = self.get_file_storage()
return storage.generate_filename(filename)
class PageGallery(Collection):
image = CollectionItem(ProxyImageItem)
class Page(models.Model):
gallery = CollectionField(
PageGallery,
verbose_name=_("gallery")
)
ΠΠ° Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌΡΠ΅ Π² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΡΠ°ΠΉΠ»Ρ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π»ΠΎΠΆΠΈΡΡ ΠΎΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π²Π°Π»ΠΈΠ΄Π°ΡΠΎΡΠΎΠ²:
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import *
from paper_uploads.validators import ImageMaxSizeValidator, ImageMinSizeValidator
class PageGallery(Collection):
image = CollectionItem(ImageItem, validators=[
ImageMinSizeValidator(640, 480),
ImageMaxSizeValidator(4000, 3000)
])
class Page(models.Model):
gallery = CollectionField(
PageGallery,
verbose_name=_("gallery")
)
ΠΠ»Π΅ΠΌΠ΅Π½ΡΡ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΉ ΡΠΎΠ·Π΄Π°ΡΡΡΡ ΠΏΠΎΡΡΠΈ ΡΠ°ΠΊΠΆΠ΅, ΠΊΠ°ΠΊ UploadedFile
ΠΈ UploadedImage
.
Π Π°Π·Π½ΠΈΡΠ° Π»ΠΈΡΡ Π² ΡΠΎΠΌ, ΡΡΠΎ Π²ΠΌΠ΅ΡΡΠΎ Π²ΡΠ·ΠΎΠ²Π° ΠΌΠ΅ΡΠΎΠ΄Π° set_owner_field()
Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΠΎ
Π²ΡΠ·Π²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ attach_to()
Π΄Π»Ρ ΠΏΡΠΈΡΠΎΠ΅Π΄ΠΈΠ½Π΅Π½ΠΈΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΠΊ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ:
from paper_uploads.models import *
collection = PageGallery.objects.create()
item = ImageItem()
item.attach_to(collection)
item.attach("/tmp/image.jpg")
item.save()
page = Page.objects.create(
gallery=collection
)
ΠΠ°ΡΠΈΠ°ΡΠΈΠΈ Π΄Π»Ρ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· Π΄Π²ΡΡ ΡΠΏΠΎΡΠΎΠ±ΠΎΠ²:
-
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡ
options
ΠΏΡΠ΅Π²Π΄ΠΎ-ΠΏΠΎΠ»ΡCollectionItem
:from paper_uploads.models import * class PageGallery(Collection): image = CollectionItem(ImageItem, options={ "variations": dict( mobile=dict( size=(640, 0), clip=False ) ) })
-
ΠΡΡΠΈΠ±ΡΡ ΠΊΠ»Π°ΡΡΠ° ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ
VARIATIONS
:from paper_uploads.models import * class PageGallery(Collection): VARIATIONS = dict( mobile=dict( size=(640, 0), clip=False ) ) image = CollectionItem(ImageItem)
{% if page.gallery %}
<div class="gallery">
{% for item in page.gallery %} {% if item.type == "image" %}
<div class="item item--{{ item.type }}">
<img
src="{{ item.url }}"
width="{{ item.width }}"
height="{{ item.height }}"
title="{{ item.title }}"
alt="{{ item.description }}"
/>
</div>
{% elif item.type == "file" %}}
<div class="item item--{{ item.type }}">
<a href="{{ item.url }}" download> Download file "{{ item.display_name }}" ({{ item.size|filesizeformat }}) </a>
</div>
{% endif %}} {% endfor %}
</div>
{% endif %}
ΠΠ»Ρ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΉ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠΉ Π±Π°Π·ΠΎΠ²ΡΠΉ ΠΊΠ»Π°ΡΡ ImageCollection
,
ΠΊΠΎΡΠΎΡΡΠΉ Π½Π΅ ΡΡΠ΅Π±ΡΠ΅Ρ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ»ΡΡΠ°Ρ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΠΊΠ»Π°ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°
ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ. ΠΡΠ΅ Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΡΡΠ°Π·Ρ, ΡΠ΅ΡΠ΅Π· Π°ΡΡΠΈΠ±ΡΡΡ ΠΊΠ»Π°ΡΡΠ°:
from django.db import models
from django.utils.translation import gettext_lazy as _
from paper_uploads.models import *
from paper_uploads.validators import ImageMaxSizeValidator, ImageMinSizeValidator
class PageGallery(ImageCollection):
UPLOAD_TO = "page/gallery",
VARIATIONS = dict(
gallery=dict(
size=(1600, 900),
)
)
VALIDATORS = [
ImageMinSizeValidator(640, 480),
ImageMaxSizeValidator(4000, 3000)
]
class Page(models.Model):
gallery = CollectionField(
PageGallery,
verbose_name=_("gallery")
)
ΠΠ°ΠΏΡΡΠΊΠ°Π΅Ρ ΠΊΠΎΠΌΠΏΠ»Π΅ΠΊΡΠ½ΡΡ ΠΏΡΠΎΠ²Π΅ΡΠΊΡ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΡΡ ΡΠ°ΠΉΠ»ΠΎΠ² ΠΈ Π²ΡΠ²ΠΎΠ΄ΠΈΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ.
Π‘ΠΏΠΈΡΠΎΠΊ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌΡΡ ΡΠ΅ΡΡΠΎΠ²:
- Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΡΠΉ ΡΠ°ΠΉΠ» ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ
- ΠΊΠ»Π°ΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π²Π»Π°Π΄Π΅Π»ΡΡΠ° (ΡΠΊΠ°Π·Π°Π½Π½ΡΠΉ Π²
owner_app_label
ΠΈowner_model_name
) ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ - Π² ΠΊΠ»Π°ΡΡΠ΅ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π²Π»Π°Π΄Π΅Π»ΡΡΠ° ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΠΏΠΎΠ»Π΅, ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ΅ Π²
owner_fieldname
- Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΉ ΡΠΊΠ°Π·Π°Π½ΠΎ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π² ΠΏΠΎΠ»Π΅
type
- ΠΌΠΎΠ΄Π΅Π»Ρ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ° ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ ΠΌΠΎΠ΄Π΅Π»ΠΈ, ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ Π² ΠΊΠ»Π°ΡΡΠ΅ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΈ
python3 manage.py check_uploads
ΠΠ°Ρ ΠΎΠ΄ΠΈΡ ΠΌΡΡΠΎΡΠ½ΡΠ΅ Π·Π°ΠΏΠΈΡΠΈ Π² ΠΠ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ ΡΠ΅, Ρ ΠΊΠΎΡΠΎΡΡΡ Π½Π΅Ρ Π²Π»Π°Π΄Π΅Π»ΡΡΠ°) ΠΈ ΠΏΡΠ΅Π΄Π»Π°Π³Π°Π΅Ρ ΠΈΡ ΡΠ΄Π°Π»ΠΈΡΡ.
ΠΠ»Π°Π΄Π΅Π»Π΅Ρ Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ Π² ΠΌΠΎΠΌΠ΅Π½Ρ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΡ ΡΡΡΠ°Π½ΠΈΡΡ
Π² ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡΠ΅ Π°Π΄ΠΌΠΈΠ½ΠΈΡΡΡΠ°ΡΠΎΡΠ°. ΠΡΠΎ ΠΏΡΠΎΠΈΡΡ
ΠΎΠ΄ΠΈΡ ΠΏΠΎΠ·ΠΆΠ΅ ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΎΠΉ Π·Π°Π³ΡΡΠ·ΠΊΠΈ ΡΠ°ΠΉΠ»Π°
Π½Π° ΡΠ΅ΡΠ²Π΅Ρ. Π ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΊΠ΅ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΌΠ΅ΠΆΠ΄Ρ ΡΡΠΈΠΌΠΈ ΡΠΎΠ±ΡΡΠΈΡΠΌΠΈ ΡΠ°ΠΉΠ» Π±ΡΠ΄Π΅Ρ ΡΠ²Π»ΡΡΡΡΡ "ΡΠΈΡΠΎΡΠΎΠΉ".
ΠΠ»Ρ ΡΠΎΠ³ΠΎ, ΡΡΠΎΠ±Ρ ΡΠ°ΠΊΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ Π½Π΅ ΡΠ΄Π°Π»ΡΠ»ΠΈΡΡ, ΠΊΠΎΠΌΠ°Π½Π΄Π° clean_uploads
ΠΈΠ³Π½ΠΎΡΠΈΡΡΠ΅Ρ
ΡΠ°ΠΉΠ»Ρ, Π·Π°Π³ΡΡΠΆΠ΅Π½Π½ΡΠ΅ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅Π³ΠΎ ΡΠ°ΡΠ°.
python3 manage.py clean_uploads
Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΉ, Π² ΠΊΠΎΡΠΎΡΡΡ Π½Π΅Ρ Π½ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°.
python3 manage.py clean_uploads
Π‘ΠΎΠ·Π΄Π°ΡΡ ΠΎΡΡΡΡΡΡΠ²ΡΡΡΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ.
python3 manage.py create_missing_variations
Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅/ΠΏΠ΅ΡΠ΅Π·Π°ΠΏΠΈΡΡ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ Π΄Π»Ρ Π²ΡΠ΅Ρ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ ΠΌΠΎΠ΄Π΅Π»ΠΈ.
# for collections
python3 manage.py recreate_variations app.Photos image
# for regular models
python3 manage.py recreate_variations app.Page image
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ Π²ΡΠ·ΠΎΠ²Π° ΡΡΠΈΡ ΠΊΠΎΠΌΠ°Π½Π΄, ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π±ΡΠ΄Π΅Ρ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΎ Π²ΡΠ±ΡΠ°ΡΡ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ.
ΠΠΎΠΆΠ½ΠΎ ΡΡΠ°Π·Ρ ΡΠΊΠ°Π·Π°ΡΡ Π½ΡΠΆΠ½ΡΠ΅ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ:
python3 manage.py recreate_variations app.Page image -- desktop mobile
Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»ΠΎΠ² Π²Π°ΡΠΈΠ°ΡΠΈΠΉ.
Π£Π΄Π°Π»ΡΡΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ°ΠΉΠ»Ρ ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π½ΡΡ
Π²Π°ΡΠΈΠ°ΡΠΈΠΉ.
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌ recreate_variations
.
# for collections
python3 manage.py remove_variations app.Photos image
# for regular models
python3 manage.py remove_variations app.Page image
ΠΡΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡΡΡ Π² ΡΠ»ΠΎΠ²Π°ΡΠ΅ PAPER_UPLOADS
.
PAPER_UPLOADS = {
"STORAGE": "django.core.files.storage.FileSystemStorage",
"STORAGE_OPTIONS": {},
"FILES_UPLOAD_TO": "files/%Y/%m/%d",
"IMAGES_UPLOAD_TO": "images/%Y/%m/%d",
"COLLECTION_FILES_UPLOAD_TO": "collections/files/%Y/%m/%d",
"COLLECTION_IMAGES_UPLOAD_TO": "collections/images/%Y/%m/%d",
"RQ_ENABLED": True,
"RQ_QUEUE_NAME": "default",
"VARIATION_DEFAULTS": {
"jpeg": dict(
quality=80,
progressive=True,
),
"webp": dict(
quality=75,
)
}
}
ΠΡΡΡ ΠΊ ΠΊΠ»Π°ΡΡΡ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ° Django.
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: django.core.files.storage.FileSystemStorage
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ°.
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: {}
ΠΡΡΡ ΠΊ ΠΏΠ°ΠΏΠΊΠ΅, Π² ΠΊΠΎΡΠΎΡΡΡ Π·Π°Π³ΡΡΠΆΠ°ΡΡΡΡ ΡΠ°ΠΉΠ»Ρ ΠΈΠ· FileField. ΠΠΎΠΆΠ΅Ρ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π΄Π»Ρ Π΄Π°ΡΡ ΠΈ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ (ΡΠΌ. upload_to).
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: files/%Y/%m/%d
ΠΡΡΡ ΠΊ ΠΏΠ°ΠΏΠΊΠ΅, Π² ΠΊΠΎΡΠΎΡΡΡ Π·Π°Π³ΡΡΠΆΠ°ΡΡΡΡ ΡΠ°ΠΉΠ»Ρ ΠΈΠ· ImageField.
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: images/%Y/%m/%d
ΠΡΡΡ ΠΊ ΠΏΠ°ΠΏΠΊΠ΅, Π² ΠΊΠΎΡΠΎΡΡΡ Π·Π°Π³ΡΡΠΆΠ°ΡΡΡΡ ΡΠ°ΠΉΠ»Ρ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΉ.
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: collections/files/%Y/%m/%d
ΠΡΡΡ ΠΊ ΠΏΠ°ΠΏΠΊΠ΅, Π² ΠΊΠΎΡΠΎΡΡΡ Π·Π°Π³ΡΡΠΆΠ°ΡΡΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΉ.
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: collections/images/%Y/%m/%d
Π Π°Π·ΠΌΠ΅ΡΡ ΠΏΡΠ΅Π²ΡΡ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠΎΠ² ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΉ Π² Π°Π΄ΠΌΠΈΠ½ΠΊΠ΅.
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: 180
x 135
ΠΠ°ΡΠΈΠ°ΡΠΈΠΈ, Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌΡΠ΅ ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡ ΠΊΠ»Π°ΡΡΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ ΠΊΠΎΠ»Π»Π΅ΠΊΡΠΈΠΉ
Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΠΏΡΠ΅Π²ΡΡ Π² Π°Π΄ΠΌΠΈΠ½ΠΊΠ΅. Π Π°Π·ΠΌΠ΅ΡΡ ΡΠ°ΠΉΠ»ΠΎΠ² Π΄ΠΎΠ»ΠΆΠ½Ρ
ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡ Ρ COLLECTION_ITEM_PREVIEW_WIDTH
ΠΈ
COLLECTION_ITEM_PREVIEW_HEIGHT
.
ΠΠΊΠ»ΡΡΠ°Π΅Ρ Π½Π°ΡΠ΅Π·ΠΊΡ ΠΊΠ°ΡΡΠΈΠ½ΠΎΠΊ Π½Π° Π²Π°ΡΠΈΠ°ΡΠΈΠΈ ΡΠ΅ΡΠ΅Π· ΠΎΡΠ»ΠΎΠΆΠ΅Π½Π½ΡΠ΅ Π·Π°Π΄Π°ΡΠΈ. Π’ΡΠ΅Π±ΡΠ΅Ρ Π½Π°Π»ΠΈΡΠΈΠ΅ ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΏΠ°ΠΊΠ΅ΡΠ° django-rq.
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: False
ΠΠ°Π·Π²Π°Π½ΠΈΠ΅ ΠΎΡΠ΅ΡΠ΅Π΄ΠΈ, Π² ΠΊΠΎΡΠΎΡΡΡ ΠΏΠΎΠΌΠ΅ΡΠ°ΡΡΡΡ Π·Π°Π΄Π°ΡΠΈ ΠΏΠΎ Π½Π°ΡΠ΅Π·ΠΊΠ΅ ΠΊΠ°ΡΡΠΈΠ½ΠΎΠΊ.
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: default
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π²Π°ΡΠΈΠ°ΡΠΈΠΉ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
ΠΠ°ΡΠ°ΠΌΠ΅ΡΡΡ, ΡΠΊΠ°Π·Π°Π½Π½ΡΠ΅ Π² ΡΡΠΎΠΌ ΡΠ»ΠΎΠ²Π°ΡΠ΅, Π±ΡΠ΄ΡΡ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½Ρ ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Π²Π°ΡΠΈΠ°ΡΠΈΠΈ β Π΅ΡΠ»ΠΈ ΡΠΎΠ»ΡΠΊΠΎ Π²Π°ΡΠΈΠ°ΡΠΈΡ ΠΈΡ ΡΠ²Π½ΠΎ Π½Π΅ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ.
ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: None
After cloning the Git repository, you should install this in a virtualenv and set up for development:
virtualenv .venv
source .venv/bin/activate
pip install -r ./requirements.txt
pre-commit install
Install npm
dependencies and build static files:
npm ci
npx webpack