У цьому посібнику показано, як реалізувати завантаження файлів з Django. Для цього створимо простий клон Instagram, який буде працювати з зображеннями.
Установка Django в Python 3
Для простоти папку з навчальним прикладом краще помістити на робочому столі, але в загальному і цілому розташування особливого значення не має. Головне, щоб директорія проекту була легко доступною.
Відкрийте командний рядок і створіть директорію insta для зберігання файлів. Для установки як Django, так і Pillow ми будемо використовувати Pipenv. Pillow є бібліотекою для обробки зображень. Для завантаження інші типів файлів Pillow не знадобиться.
Активуємо нове віртуальне середовище:
$ cd ~/Desktop
$ mkdir insta && cd insta
$ pipenv install django==2.1.5 pillow==5.4.1
$ pipenv shell
(insta) $
Про активацію віртуального середовища повідомить зміна в (insta). Ви також можете в будь-який час ввести команду exit для виходу і pipenv shell для повторного входу.
Створення проекту і додатку в Django
Створимо новий проект Django під назвою insta_project і новий додаток, який назвемо posts.
(insta) $ django-admin startproject insta_project .
(insta) $ python manage.py startapp posts
Так як ми додали новий додаток, ми повинні повідомити про це Django в нижній частині конфігурації INSTALLED_APPS в settings.py.
# insta_project / settings.py
INSTALLED_APPS = [
'django.contrib.admin' ,
'django.contrib.auth' ,
'django.contrib.contenttypes' ,
'django.contrib.sesions' ,
'django.contrib.messages' ,
'django.contrib.staticfiles' ,
'posts.apps.PostsConfig' , # нове
]
Тепер запускаємо python manage.py migrate для установки бази даних нового проекту.
(insta) $ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying sessions.0001_initial... OK
Створюємо моделі в Django
Найкраще починати з моделі бази даних. У нашому випадку у моделі Post буде тільки два поля: title і cover. Нижче ми також додамо метод __str__(), щоб title відобразився в інтерфейсі адміністратора Django.
# posts/models.py
from django.db import models
class Post(models.Model):
title = models.TextField()
cover = models.ImageField(upload_to='images/')
def __str__(self):
return self.title
Місцезнаходження завантаження image буде в MEDIA_ROOT/images. В Django локацією для MEDIA_ROOT за замовчуванням є папка, звідки будуть завантажуватися всі файли користувача.
У разі, коли замість зображення потрібно завантажити інший файл , потрібно просто поміняти ImageField на FileField.
Налаштування MEDIA_ROOT в Django 2
Відкрийте insta_project/settings.py в текстовому редакторі. Нам буде потрібно додати дві нові конфігурації. За замовчуванням MEDIA_URL і MEDIA_ROOT є порожніми і не відображаються на екрані, тому їх необхідно налаштувати:
- MEDIA_ROOT є шляхом файлової системи, куди користувачі будуть завантажувати файли;
- MEDIA_URL є URL, який ми можемо використовувати в шаблонах для файлів.
# insta_project/settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
Назву media використовувати не обов'язково, можна вибрати будь-яку, просто в Django media використовується за замовчуванням. Ми також створюємо папку images всередині для простоти навігації.
(insta) $ mkdir media
(insta) $ mkdir media/images
Панель адміністратора в Django
Зараз ми оновимо файл posts/admin.py, після чого в Django з'явиться можливість використовувати додаток Post від імені адміністратора.
# posts/admin.py
from django.contrib import admin
from .models import Post
admin.site.register(Post)
Все налаштоване! Генеруємо новий файл міграції.
(insta) $ python manage.py makemigrations
Migrations for 'posts':
posts/migrations/0001_initial.py
- Create model Post
Тепер запускаємо migrate для оновлення бази даних.
(insta) $ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, posts, session
s
Running migrations:
Applying posts.0001_initial... OK
Тепер можна створити обліковий запис superuser для доступу до інтерфейсу адміністратора, після чого виконати runserver для першого запуску локального веб-сервера :
(insta) $ python manage.py createsuperuser
(insta) $ python manage.py runserver
Якщо набрати в адресному рядку браузера http://127.0.0.1:8000/admin, з'явиться можливість зайти в адмінку Django . Ви будете направлені на наступну сторінку:
Натисніть на + Add біля Posts. Тут можна додати все, що хочете, але в цьому посібнику ми створюємо запис із зображенням талісмана Django - поні.
Після натискання « Save » ви будете перенаправлені на сторінку Posts, де розташовані всі наявні записи.
Тепер якщо ви загляньте в папку media в вашому проекті, то побачите, що в директорії images з'явилося зображення djangopony.png. Як і було сказано раніше, MEDIA_URL потрібен саме для цього.
Отже, з основами ми розібралися. Тепер розберемося з тим, як відображати записи, використовувати urls.py, views.py і шаблони файлів.
Налаштування urls.py в Django
Аспектом роботи з Django, який може дещо заплутати, є той факт, що найчастіше для однієї веб-сторінки потрібно 4 різних, але взаємопов'язаних файли: models.py, urls.py, views.py і html-шаблони. Тут ми будемо розбирати терміни у такому порядку: моделі (models) -> urls -> уявлення (views) -> шаблони (templates). З моделлю ми вже розібралися, так що перейдемо до URL.
Нам знадобляться оновити файл urls.py. Спочатку на проектному рівні insta_project/urls.py ми додамо обсяги імпорту для settings, include і static.
Після цього ми визначимо шлях для застосування posts. Варто відзначити, що якщо настройки в режимі DEBUG, то MEDIA_URL також потрібно додати. В іншому випадку не вийде побачити файли зображення.
# insta_project/urls.py
from django.contrib import admin
from django.conf import settings # new
from django.urls import path, include # new
from django.conf.urls.static import static # new
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('posts.urls')), # new
]
if settings.DEBUG: # new
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Далі необхідно розсортувати шляхи URL в межах програми posts. Насамперед створюється файл через linux команду touch .
( insta ) $ touch posts / urls.py
Потім ми винесемо всі записи на головну сторінку, для цього використовуємо порожній рядок ' ' в якості шляху.
# posts/urls.py
from django.urls import path
from .views import HomePageView
urlpatterns = [
path('', HomePageView.as_view(), name='home'),
]
Це буде пов'язано з view HomePageView, створенням якого ми займемося далі.
views в Django
Тут можна використовувати звичайний ListView, заснований на класі, а потім імпортувати модель Post. Після цього треба створити HomePageView, що використовує дану модель, а також шаблон під назвою home.html.
# posts/views.py
from django.views.generic import ListView
from .models import Post
class HomePageView(ListView):
model = Post
template_name = 'home.html'
Тепер переходимо до файлу-шаблону під назвою home.html.
templates в Django
При виборі локації для шаблону є два варіанти. Ми могли б помістити його в posts, що розташований в posts/templates/posts/home.html, але тоді структура стане надмірною. Крім того, якщо розміщення схем глибоко в папках своїх додатків, їх буде складніше розбирати. Саме тому для уроку на проектному рівні ми створимо окрему директорію templates.
$ mkdir templates
$ touch templates/home.html
Далі вкажемо Django, щоб він також розглядав дану директорію при пошуку шаблонів, оновивши конфігурацію TEMPLATES в insta_project/settings.py.
# insta_project/settings.py
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR, 'templates')], # new
...
},
]
Файл шаблону home.html показує title і image всіх наших записів. У Instagram все було б так само.
<!-- templates/home.html -->
<h1>Django Image Uploading</h1>
<ul>
{% for post in object_list %}
<h2>{{ post.title }}</h2>
<img src="{{ post.cover.url}}" alt="{{ post.title }}">
{% endfor %}
</ul>
От і все. Запустіть сервер командою python manage.py runserver і перейдіть на домашню сторінку http://127.0.0.1:8000. У разі необхідності перезавантажте сторінку.
Вуаля! Если вы добавите дополнительные посты с заголовками и картинками от имени администратора, то они появятся на домашней странице.
Форма для додавання запису в Django
Тепер ми можемо створити html форму для того, щоб звичайні користувачі без доступу в адмінку могли також додавати записи і завантажувати файли. Це передбачає створення нової сторінки за допомогою форми.
Давайте почнемо з файлу views.py. Назвемо нове уявлення CreatePostView. Воно розширить вбудоване в Django CreateView. Також імпортуємо reverse_lazy, який відповідає за повернення на домашню сторінку після відправки форми через POST запит.
У поданні ми вказуємо model, form_class, що буде створений далі, template_name і, звичайно ж, success_url, який буде отриманий після відправки.
# posts/views.py
from django.views.generic import ListView, CreateView # новый
from django.urls import reverse_lazy # новый
from .forms import PostForm # новый
from .models import Post
class HomePageView(ListView):
model = Post
template_name = 'home.html'
class CreatePostView(CreateView): # новый
model = Post
form_class = PostForm
template_name = 'post.html'
success_url = reverse_lazy('home')
Займемося формою. Вона створюється наступним чином:
(insta) $ touch posts/forms.py
Ми можемо розширити вбудований в Django ModelForm. Тут у базовій формі потрібно уточнити правильну модель Post і назви, що виводяться на екран полів. В даному випадку це title і cover.
# posts/forms.py
from django import forms
from .models import Post
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'cover']
Для форми створюється спеціальна сторінки, URL-шлях якої post/.
# posts/urls.py
from django.urls import path
from .views import HomePageView, CreatePostView # new
urlpatterns = [
path('', HomePageView.as_view(), name='home'),
path('post/', CreatePostView.as_view(), name='add_post') # new
]
Створюємо новий шаблон.
(insta) $ touch templates/post.html
Вносимо в нього заголовок і форму. Для захисту важливо завжди додавайте csrf_token. Уточнюємо form.as_p, через що Django виведе кожне поле у вигляді окремого параграфа.
<!-- templates/post.html -->
<h1>Create Post Page</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit New Post</button>
</form>
Ось і воно! Переконайтеся, що сервер запущений, і перейдіть на сторінку http://127.0.0.1:8000/post/.
Після підтвердження створення нового запису ви будете перенаправлені на домашню сторінку, де відображаються всі наявні пости.
Наступні кроки
І що тепер? Багатьом напевно захочеться накласти певні обмеження на розмір картинки. Це можна зробити в файлі models.py або за допомогою CSS. Також багатьом напевно захочеться додати опції редагування або видалення для записів.
З огляду на важливе оновлення, не рекомендується розміщувати файли в Django. Краще налаштувати виділену зовнішню службу, наприклад, мережу доставки контенту Content Delivery Network (CDN).
По матеріалам: python-scripts.com
0 комментариев
Добавить комментарий