ImageField

1. ํ•„์š”ํ•œ package ์„ค์น˜ํ•˜๊ธฐ

1-1. ImageField

  • ๋‹จ์ˆœ ImageField๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” pillow ํŒจํ‚ค์ง€๊ฐ€ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•˜๋‹ค.

pip install pillow

1-2. resizing

  • Resizing์„ ์œ„ํ•ด์„œ๋Š” pilkit, django-imagekit ํŒจํ‚ค์ง€๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

pip install pilkit django-imagekit

2. model์— image column ์ •์˜

posts > models.py

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    image = models.ImageField(blank=True)
    # DB ์ €์žฅ x, ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด ์ž˜๋ผ์„œ ํ‘œํ˜„
    image_thumbnail = ImageSpecField(source='image',
                                      processors=[ResizeToFill(300, 300)],
                                      format='JPEG',
                                      options={'quality': 60})
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    #์ข‹์•„์š” ๊ธฐ๋Šฅ
    like_users = models.ManyToManyField(settings.AUTH_USER_MODEL,
                                    related_name='like_posts')

3. view์— request.FILES ์ถ”๊ฐ€

posts > views.py

@login_required
def create(request):
    if request.method == 'POST':
        form = PostForm(request.POST, request.FILES)
        if form.is_valid():
            post = form.save(commit=False) # ์ถ”๊ฐ€ํ•จ
            post.user = request.user
            post.save()
            return redirect('posts:index')
        messages.warning(request, 'Please check the form submitted')
    else:
        form = PostForm()
    context = {
        'form': form
    }
    return render(request, 'posts/forms.html', context)


def update(request):
    if request.method == 'POST':
        form = CustomUserChangeForm(request.POST, instance=request.user)
        if form.is_valid():
            form.save()
            return redirect('posts:index')
    else:
        form = CustomUserChangeForm(instance=request.user)
    context ={
        'form':form
    }
    return render(request, 'accounts/update.html', context)

4. settings.py ์ˆ˜์ •

# media file ์ €์žฅ ๊ฒฝ๋กœ
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

MEDIA_URL = '/media/'

5. urls.py์— ๊ฒฝ๋กœ ์ถ”๊ฐ€

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('posts/', include('posts.urls')),
    path('accounts/', include('accounts.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

6. Templates ์ˆ˜์ •

forms.html

<form action="" method="POST" enctype="multipart/form-data">

detail.html

    <!--image ์ถœ๋ ฅ์šฉ-->
    <img src="{{post.image.url}}"/>
    <img src="{{post.image_thumbnail.url}}"/>

migrations

$ python manage.py makemigrations
# default๊ฐ’ ์—†์ด NOT NULL๋ฅผ ์ง€์ • => ๊ธฐ์กด ๋ ˆ์ฝ”๋“œ์— ๊ฐ’์ด ํ•„์š”ํ•˜๋‹ค.
You are trying to add a non-nullable field 'image' to article without a default; we can't do that (the database needs something to populate existing rows).
# 2๊ฐ€์ง€ ์˜ต์…˜ ์ œ์‹œ
Please select a fix:
 # 1) ๋””ํดํŠธ ๊ฐ’์„ ์ง€๊ธˆ ์„ค์ • => python console
 1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
 # 2) ์ข…๋ฃŒํ•˜๊ณ  ์ง์ ‘ models.py์— default ์„ค์ •
 2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt

django-imagekit library

Image ๋‚ด๋ถ€์ ์œผ๋กœ thumbnail์— ๋งž๊ฒŒ ์ž๋ฅด๊ธฐ

Download & usage

https://github.com/matthewwithanm/django-imagekit

Installation

pip install pilkit django-imagekit

์›๋ณธ ์ž์ฒด๋ฅผ ์ž˜๋ผ์„œ ์ €์žฅ

ProcessedImageField(upload_to='avatars',
                                           processors=[ResizeToFill(100, 50)],
                                           format='JPEG',
                                           options={'quality': 60})

Last updated