Sorl-thumbnail: ν‚€ κ°’ μ €μž₯μ†Œμ˜ μ†ŒμŠ€ 이미지에 썸넀일이 μ—°κ²°λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

에 λ§Œλ“  2014λ…„ 10μ›” 14일  Β·  3μ½”λ©˜νŠΈ  Β·  좜처: jazzband/sorl-thumbnail

λ‹€μŒκ³Ό 같은 행동을 κ΄€μ°°ν–ˆμŠ΅λ‹ˆλ‹€.

λ‚΄ νŽ˜μ΄μ§€μ—λŠ” {% thumbnail %} ν…œν”Œλ¦Ώ νƒœκ·Έμ— λŒ€ν•œ 두 번의 호좜이 있으며 각각 λ‹€λ₯Έ 크기의 λ™μΌν•œ μ†ŒμŠ€ μ΄λ―Έμ§€μ˜ μΆ•μ†ŒνŒμ„ μš”μ²­ν•©λ‹ˆλ‹€. 이와 같이:

{% thumbnail user.get_profile.avatar_image "46x46" crop="center" as im %} .. {% endthumbnail %}
{% thumbnail user_profile.avatar_image "187x187" crop="center" as im %} .. {% endthumbnail %}

(ν˜ΈμΆœμ€ λ‹€λ₯Έ Django ν…œν”Œλ¦Ώμ—μ„œ μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€)

sorl-thumbnail이 썸넀일을 찾을 수 μ—†μœΌλ©΄ μ˜ˆμƒλŒ€λ‘œ μƒμ„±λ©λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μΆ•μ†ŒνŒ 쀑 ν•˜λ‚˜κ°€ ν‚€ κ°’ μ €μž₯μ†Œμ˜ sorl-thumbnail||thumbnails||xxx ν•­λͺ©μ—μ„œ μ°Έμ‘°λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

νŽ˜μ΄μ§€κ°€ λ Œλ”λ§λœ ν›„ ν‚€ κ°’ μ €μž₯μ†ŒλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

# select * from thumbnail_kvstore;
                             key                              |                                                                   value                                                                    
--------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------
 sorl-thumbnail||image||3314722c993608c1dab30949d2504172      | {"storage": "outdoorish.storage.OverwriteStorage", "name": "profiles/avatars/2205.jpg", "size": [300, 423]}
 sorl-thumbnail||image||4d545ece8fb09c9176996000cddc0fac      | {"storage": "django.core.files.storage.FileSystemStorage", "name": "cache/7c/ab/7cab89bcadad6122d441e6d5443fccc2.jpg", "size": [187, 187]}
 sorl-thumbnail||thumbnails||3314722c993608c1dab30949d2504172 | ["4d545ece8fb09c9176996000cddc0fac"]
 sorl-thumbnail||image||256cd182b71debc11e8aae0ed8ee1a9d      | {"storage": "django.core.files.storage.FileSystemStorage", "name": "cache/b2/71/b27103adff0bdbba7d05fc98a51be131.jpg", "size": [46, 46]}
(4 rows)

이미지 쀑 ν•˜λ‚˜κ°€ μ†ŒμŠ€ νŒŒμΌμ— μ—°κ²°λ˜μ§€ μ•Šμ€ μ΄μœ λŠ” λ¬΄μ—‡μž…λ‹ˆκΉŒ? 이 행동이 μ˜λ„μ μž…λ‹ˆκΉŒ? ( sorl.thumbnail.delete ν˜ΈμΆœν•  λ•Œ 썸넀일이 μ‚­μ œλ˜μ§€ μ•ŠλŠ” 원인이라고 μƒκ°ν•˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.)

sorl-thumbnail==11.12.1b

이것은 썸넀일 μƒμ„±μ˜ Django λ‘œκ·Έμž…λ‹ˆλ‹€.

첫 번째 썸넀일 κ°€μ Έμ˜€κΈ°/생성 둜그:

2014-10-14 14:58:35,131 DEBUG base Getting thumbnail for file [profiles/avatars/2205.jpg] at [187x187] | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/sorl/thumbnail/base.py:67 (get_thumbnail), PID:8096 Thread:140412452124416
2014-10-14 14:58:35,182 DEBUG util (0.001) SELECT "thumbnail_kvstore"."key", "thumbnail_kvstore"."value" FROM "thumbnail_kvstore" WHERE "thumbnail_kvstore"."key" = 'sorl-thumbnail||image||4d545ece8fb09c9176996000cddc0fac' ; args=(u'sorl-thumbnail||image||4d545ece8fb09c9176996000cddc0fac',) | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412452124416
2014-10-14 14:58:35,210 DEBUG base Creating thumbnail file [cache/7c/ab/7cab89bcadad6122d441e6d5443fccc2.jpg] at [187x187] with [{'rounded': None, 'padding_color': '#ffffff', 'format': 'JPEG', 'colorspace': 'RGB', 'cropbox': None, 'padding': False, 'upscale': True, 'crop': u'center', 'image_info': {'jfif_version': (1, 1), 'jfif': 257, 'jfif_unit': 1, 'jfif_density': (72, 72), 'dpi': (72, 72)}, 'quality': 95}] | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/sorl/thumbnail/base.py:148 (_create_thumbnail), PID:8096 Thread:140412452124416
2014-10-14 14:58:35,248 DEBUG util (0.001) SELECT "thumbnail_kvstore"."key", "thumbnail_kvstore"."value" FROM "thumbnail_kvstore" WHERE "thumbnail_kvstore"."key" = 'sorl-thumbnail||image||3314722c993608c1dab30949d2504172' ; args=(u'sorl-thumbnail||image||3314722c993608c1dab30949d2504172',) | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412452124416
2014-10-14 14:58:35,273 DEBUG util (0.001) SELECT "thumbnail_kvstore"."key", "thumbnail_kvstore"."value" FROM "thumbnail_kvstore" WHERE "thumbnail_kvstore"."key" = 'sorl-thumbnail||image||3314722c993608c1dab30949d2504172' ; args=(u'sorl-thumbnail||image||3314722c993608c1dab30949d2504172',) | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412452124416
2014-10-14 14:58:35,308 DEBUG util (0.001) INSERT INTO "thumbnail_kvstore" ("key", "value") VALUES ('sorl-thumbnail||image||3314722c993608c1dab30949d2504172', '{"storage": "outdoorish.storage.OverwriteStorage", "name": "profiles/avatars/2205.jpg", "size": [300, 423]}'); args=(u'sorl-thumbnail||image||3314722c993608c1dab30949d2504172', '{"storage": "outdoorish.storage.OverwriteStorage", "name": "profiles/avatars/2205.jpg", "size": [300, 423]}') | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412452124416
2014-10-14 14:58:35,345 DEBUG util (0.001) SELECT "thumbnail_kvstore"."key", "thumbnail_kvstore"."value" FROM "thumbnail_kvstore" WHERE "thumbnail_kvstore"."key" = 'sorl-thumbnail||image||4d545ece8fb09c9176996000cddc0fac' ; args=(u'sorl-thumbnail||image||4d545ece8fb09c9176996000cddc0fac',) | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412452124416
2014-10-14 14:58:35,371 DEBUG util (0.000) INSERT INTO "thumbnail_kvstore" ("key", "value") VALUES ('sorl-thumbnail||image||4d545ece8fb09c9176996000cddc0fac', '{"storage": "django.core.files.storage.FileSystemStorage", "name": "cache/7c/ab/7cab89bcadad6122d441e6d5443fccc2.jpg", "size": [187, 187]}'); args=(u'sorl-thumbnail||image||4d545ece8fb09c9176996000cddc0fac', '{"storage": "django.core.files.storage.FileSystemStorage", "name": "cache/7c/ab/7cab89bcadad6122d441e6d5443fccc2.jpg", "size": [187, 187]}') | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412452124416
2014-10-14 14:58:35,426 DEBUG util (0.001) SELECT "thumbnail_kvstore"."key", "thumbnail_kvstore"."value" FROM "thumbnail_kvstore" WHERE "thumbnail_kvstore"."key" = 'sorl-thumbnail||thumbnails||3314722c993608c1dab30949d2504172' ; args=(u'sorl-thumbnail||thumbnails||3314722c993608c1dab30949d2504172',) | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412452124416
2014-10-14 14:58:35,449 DEBUG util (0.001) SELECT "thumbnail_kvstore"."key", "thumbnail_kvstore"."value" FROM "thumbnail_kvstore" WHERE "thumbnail_kvstore"."key" = 'sorl-thumbnail||thumbnails||3314722c993608c1dab30949d2504172' ; args=(u'sorl-thumbnail||thumbnails||3314722c993608c1dab30949d2504172',) | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412452124416
2014-10-14 14:58:35,472 DEBUG util (0.000) INSERT INTO "thumbnail_kvstore" ("key", "value") VALUES ('sorl-thumbnail||thumbnails||3314722c993608c1dab30949d2504172', '["4d545ece8fb09c9176996000cddc0fac"]'); args=(u'sorl-thumbnail||thumbnails||3314722c993608c1dab30949d2504172', '["4d545ece8fb09c9176996000cddc0fac"]') | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412452124416

두 번째 썸넀일 κ°€μ Έμ˜€κΈ°/생성 둜그:

2014-10-14 14:58:37,314 DEBUG base Getting thumbnail for file [profiles/avatars/2205.jpg] at [46x46] | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/sorl/thumbnail/base.py:67 (get_thumbnail), PID:8096 Thread:140412426946304
2014-10-14 14:58:37,333 DEBUG util (0.001) SELECT "thumbnail_kvstore"."key", "thumbnail_kvstore"."value" FROM "thumbnail_kvstore" WHERE "thumbnail_kvstore"."key" = 'sorl-thumbnail||image||256cd182b71debc11e8aae0ed8ee1a9d' ; args=(u'sorl-thumbnail||image||256cd182b71debc11e8aae0ed8ee1a9d',) | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412426946304
2014-10-14 14:58:37,345 DEBUG base Creating thumbnail file [cache/b2/71/b27103adff0bdbba7d05fc98a51be131.jpg] at [46x46] with [{'rounded': None, 'padding_color': '#ffffff', 'format': 'JPEG', 'colorspace': 'RGB', 'cropbox': None, 'padding': False, 'upscale': True, 'crop': u'center', 'image_info': {'jfif_version': (1, 1), 'jfif': 257, 'jfif_unit': 1, 'jfif_density': (72, 72), 'dpi': (72, 72)}, 'quality': 95}] | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/sorl/thumbnail/base.py:148 (_create_thumbnail), PID:8096 Thread:140412426946304
2014-10-14 14:58:37,386 DEBUG util (0.001) SELECT "thumbnail_kvstore"."key", "thumbnail_kvstore"."value" FROM "thumbnail_kvstore" WHERE "thumbnail_kvstore"."key" = 'sorl-thumbnail||image||256cd182b71debc11e8aae0ed8ee1a9d' ; args=(u'sorl-thumbnail||image||256cd182b71debc11e8aae0ed8ee1a9d',) | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412426946304
2014-10-14 14:58:37,390 DEBUG util (0.001) INSERT INTO "thumbnail_kvstore" ("key", "value") VALUES ('sorl-thumbnail||image||256cd182b71debc11e8aae0ed8ee1a9d', '{"storage": "django.core.files.storage.FileSystemStorage", "name": "cache/b2/71/b27103adff0bdbba7d05fc98a51be131.jpg", "size": [46, 46]}'); args=(u'sorl-thumbnail||image||256cd182b71debc11e8aae0ed8ee1a9d', '{"storage": "django.core.files.storage.FileSystemStorage", "name": "cache/b2/71/b27103adff0bdbba7d05fc98a51be131.jpg", "size": [46, 46]}') | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412426946304
2014-10-14 14:58:37,429 DEBUG util (0.001) SELECT "thumbnail_kvstore"."key", "thumbnail_kvstore"."value" FROM "thumbnail_kvstore" WHERE "thumbnail_kvstore"."key" = 'sorl-thumbnail||thumbnails||3314722c993608c1dab30949d2504172' ; args=(u'sorl-thumbnail||thumbnails||3314722c993608c1dab30949d2504172',) | File:/home/anton/.virtualenvs/outdoorish/lib/python2.7/site-packages/django/db/backends/util.py:50 (execute), PID:8096 Thread:140412426946304

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

μ½”λ“œλ₯Ό 쑰금 νŒŒν—€μ³λ³΄λ‹ˆ KVStore._set_raw() ( cached_db_kvstore.py ) κΈ°λŠ₯에 λ¬Έμ œκ°€ μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€ (μ½”λ“œ 라인 링크: https://github.com/mariocesar/sorl- 썸넀일/blob/master/sorl/thumbnail/kvstores/cached_db_kvstore.py#L43 )

상황은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.
_set_raw() ν•¨μˆ˜λŠ” λ‹€μŒ λ§€κ°œλ³€μˆ˜(A)둜 ν˜ΈμΆœλ©λ‹ˆλ‹€.

key: thumbnail||thumbnails||3314722c993608c1dab30949d2504172
value: ["4d545ece8fb09c9176996000cddc0fac", "256cd182b71debc11e8aae0ed8ee1a9d"]

KV μ €μž₯μ†Œ(Postgres λ°μ΄ν„°λ² μ΄μŠ€)에 λ‹€μŒ λ§€κ°œλ³€μˆ˜(B)κ°€ μžˆλŠ” ν•­λͺ©μ΄ 이미 μžˆμŠ΅λ‹ˆλ‹€.

key: thumbnail||thumbnails||3314722c993608c1dab30949d2504172
value: ["4d545ece8fb09c9176996000cddc0fac"]

이게 문제 μ•Ό:
이제 _set_raw() λŠ” KVStoreModel.objects.get_or_create() ν˜ΈμΆœν•˜κ³  λ°μ΄ν„°λ² μ΄μŠ€((A), ν•˜λ‚˜μ˜ 썸넀일이 μ°Έμ‘°λ˜λŠ” ν•­λͺ©)μ—μ„œ ν•­λͺ©μ„ κ°€μ Έμ˜΅λ‹ˆλ‹€. 그런 λ‹€μŒ 두 개의 μΆ•μ†ŒνŒ(B)에 λŒ€ν•œ μ°Έμ‘°κ°€ μžˆλŠ” ν•­λͺ©μ„ μΊμ‹œ( django.core.cache.backends.locmem.LocMemCache )에 μ €μž₯ν•©λ‹ˆλ‹€.

ν•­λͺ©(B)의 μƒˆ 버전은 λ°μ΄ν„°λ² μ΄μŠ€μ— μ €μž₯λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 이미지λ₯Ό λ³€κ²½ν•˜λ©΄ μΆ•μ†ŒνŒ 쀑 ν•˜λ‚˜λ§Œ μ—…λ°μ΄νŠΈλ˜κ³  λ‹€λ₯Έ ν•˜λ‚˜λŠ” κ·ΈλŒ€λ‘œ μœ μ§€λ©λ‹ˆλ‹€. thumbnail||thumbnails||3314722c993608c1dab30949d2504172 ν•­λͺ©μ—μ„œ μ°Έμ‘°ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

κ΄€λ¦¬μž 쀑 ν•œ λͺ…이 문제λ₯Ό μž¬ν˜„ν•  수 μžˆλ„λ‘ 문제λ₯Ό μ„€λͺ…ν–ˆμœΌλ©΄ ν•©λ‹ˆλ‹€. 이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 데 도움이 λœλ‹€λ©΄ 정말 쒋을 κ²ƒμž…λ‹ˆλ‹€! 감사 ν•΄μš”!

λͺ¨λ“  3 λŒ“κΈ€

이에 λŒ€ν•œ μ—…λ°μ΄νŠΈκ°€ μžˆμŠ΅λ‹ˆκΉŒ? 이미지 쀑 ν•˜λ‚˜κ°€ ν‚€ κ°’ μ €μž₯μ†Œμ˜ μ†ŒμŠ€ νŒŒμΌμ— μ—°κ²°λ˜μ§€ μ•Šμ€ 이유λ₯Ό μ„€λͺ…ν•  수 μžˆλŠ” μ‚¬λžŒμ΄ μžˆμŠ΅λ‹ˆκΉŒ?

이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 데 도움을 μ£Όκ³  μ‹Άμ§€λ§Œ μ–΄λ””μ„œλΆ€ν„° μ‹œμž‘ν•΄μ•Ό ν•˜λŠ”μ§€μ— λŒ€ν•œ 포인터가 ν•„μš”ν•©λ‹ˆλ‹€!

μ½”λ“œλ₯Ό 쑰금 νŒŒν—€μ³λ³΄λ‹ˆ KVStore._set_raw() ( cached_db_kvstore.py ) κΈ°λŠ₯에 λ¬Έμ œκ°€ μžˆλŠ” 것 κ°™μŠ΅λ‹ˆλ‹€ (μ½”λ“œ 라인 링크: https://github.com/mariocesar/sorl- 썸넀일/blob/master/sorl/thumbnail/kvstores/cached_db_kvstore.py#L43 )

상황은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.
_set_raw() ν•¨μˆ˜λŠ” λ‹€μŒ λ§€κ°œλ³€μˆ˜(A)둜 ν˜ΈμΆœλ©λ‹ˆλ‹€.

key: thumbnail||thumbnails||3314722c993608c1dab30949d2504172
value: ["4d545ece8fb09c9176996000cddc0fac", "256cd182b71debc11e8aae0ed8ee1a9d"]

KV μ €μž₯μ†Œ(Postgres λ°μ΄ν„°λ² μ΄μŠ€)에 λ‹€μŒ λ§€κ°œλ³€μˆ˜(B)κ°€ μžˆλŠ” ν•­λͺ©μ΄ 이미 μžˆμŠ΅λ‹ˆλ‹€.

key: thumbnail||thumbnails||3314722c993608c1dab30949d2504172
value: ["4d545ece8fb09c9176996000cddc0fac"]

이게 문제 μ•Ό:
이제 _set_raw() λŠ” KVStoreModel.objects.get_or_create() ν˜ΈμΆœν•˜κ³  λ°μ΄ν„°λ² μ΄μŠ€((A), ν•˜λ‚˜μ˜ 썸넀일이 μ°Έμ‘°λ˜λŠ” ν•­λͺ©)μ—μ„œ ν•­λͺ©μ„ κ°€μ Έμ˜΅λ‹ˆλ‹€. 그런 λ‹€μŒ 두 개의 μΆ•μ†ŒνŒ(B)에 λŒ€ν•œ μ°Έμ‘°κ°€ μžˆλŠ” ν•­λͺ©μ„ μΊμ‹œ( django.core.cache.backends.locmem.LocMemCache )에 μ €μž₯ν•©λ‹ˆλ‹€.

ν•­λͺ©(B)의 μƒˆ 버전은 λ°μ΄ν„°λ² μ΄μŠ€μ— μ €μž₯λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 이미지λ₯Ό λ³€κ²½ν•˜λ©΄ μΆ•μ†ŒνŒ 쀑 ν•˜λ‚˜λ§Œ μ—…λ°μ΄νŠΈλ˜κ³  λ‹€λ₯Έ ν•˜λ‚˜λŠ” κ·ΈλŒ€λ‘œ μœ μ§€λ©λ‹ˆλ‹€. thumbnail||thumbnails||3314722c993608c1dab30949d2504172 ν•­λͺ©μ—μ„œ μ°Έμ‘°ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

κ΄€λ¦¬μž 쀑 ν•œ λͺ…이 문제λ₯Ό μž¬ν˜„ν•  수 μžˆλ„λ‘ 문제λ₯Ό μ„€λͺ…ν–ˆμœΌλ©΄ ν•©λ‹ˆλ‹€. 이 문제λ₯Ό ν•΄κ²°ν•˜λŠ” 데 도움이 λœλ‹€λ©΄ 정말 쒋을 κ²ƒμž…λ‹ˆλ‹€! 감사 ν•΄μš”!

λ‚˜λŠ” ν˜Όμžκ°€ μ•„λ‹™λ‹ˆλ‹€ :) 제발, 이 μˆ˜μ • 사항을 λ³‘ν•©ν•˜μ‹­μ‹œμ˜€. 맀우 ν•„μš”ν•©λ‹ˆλ‹€!

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰