Створюємо форму завантаження файлів в Django

  • 3 апреля, 14:27
  • 5372
  • 0

У цьому посібнику показано, як реалізувати завантаження файлів з Django. Для цього створимо простий клон Instagram, який буде працювати з зображеннями.

Створюємо форму завантаження файлів в Django

Установка 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 є порожніми і не відображаються на екрані, тому їх необхідно налаштувати:

  1. MEDIA_ROOT є шляхом файлової системи, куди користувачі будуть завантажувати файли;
  2. 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 комментариев
Сортировка:
Добавить комментарий

IT Новости

Смотреть все