На большинстве веб-сайтов мы часто имеем дело с мультимедийными данными, такими как изображения, файлы и т. д. В django мы можем работать с изображениями с помощью поля модели ImageField
.
В этой статье мы создали приложение image_app
в тестовом проекте с названием image_upload.
Первым делом добавим в файл settings.py
приведенный ниже код .
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
MEDIA_ROOT - это путь к серверу для хранения файлов.
MEDIA_URL - это ссылочный URL-адрес для браузера для доступа к файлам через HTTP.
В файле urls.py
мы должны отредактировать конфигурацию следующим образом
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
Пример models.py
должен быть таким, поскольку мы создали модель Hotel, в которой определили поля для названия отеля и его изображения.
# models.py
class Hotel(models.Model):
name = models.CharField(max_length=50)
hotel_Main_Img = models.ImageField(upload_to='images/')
В параметре upload_to
указывается, в каком каталоге должны находиться изображения, по умолчанию **django** создает каталог в каталоге media , который будет автоматически создан, когда мы загружаем изображение. Нет необходимости явно создавать каталог media .
Мы должны создать файл forms.py
для модели нашей формы
# forms.py
from django import forms
from .models import *
class HotelForm(forms.ModelForm):
class Meta:
model = Hotel
fields = ['name', 'hotel_Main_Img']
**Django** будет неявно обрабатывать проверку формы без явного объявления в скрипте, и он создаст аналогичные поля формы на странице в соответствии с полями модели, которые мы указали в models.py
.
В этом преимущество модельной формы.
Теперь создадим каталог шаблонов,image_app
в котором мы должны создать html-файл для загрузки изображений. HTML-файл должен выглядеть так.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hotel_image</title>
</head>
<body>
<form method = "post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
</body>
</html>
При выполнении запроса POST мы должны каким-то образом кодировать данные, которые образуют тело запроса. Итак, нам нужно указать формат кодирования в теге формы. multipart/form-data
значительно сложнее, но позволяет включать в данные целые файлы.
csrf_token
предназначен для защиты от подделки межсайтовых запросов.
form.as_p
просто оборачивает все элементы в теги абзаца HTML. Преимущество заключается в отсутствии необходимости писать цикл в шаблоне для явного добавления HTML для окружения каждого заголовка и поля.
В views.py
добавим код представления чтобы принять запрос от пользователя и вернуть некоторую HTML - страницу.
from django.http import HttpResponse
from django.shortcuts import render, redirect
from .forms import *
# Create your views here.
def hotel_image_view(request):
if request.method == 'POST':
form = HotelForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('success')
else:
form = HotelForm()
return render(request, 'hotel_image_form.html', {'form' : form})
def success(request):
return HttpResponse('successfully uploaded')
всякий раз, когда происходит обращение к hotel_image_view
с помощью POST
-запроса, мы создаем экземпляр модели, form = HotelForm(request.POST, request.FILES)
изображение формы будет храниться в request.FILES
. Если он действителен, сохраним в базе данных и перенаправим на URL-адрес, который указывает на успешную загрузку изображения. Если метод не POST, мы выполняем рендеринг с созданным шаблоном html.
urls.py
будет выглядеть так -
from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from .views import *
urlpatterns = [
path('image_upload', hotel_image_view, name = 'image_upload'),
path('success', success, name = 'success'),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
Теперь создадим миграции и запустим dev-сервер.
Когда мы нажимаем URL-адрес в браузере, он выглядит вот так.
После загрузки изображение будет успешным.
Теперь в каталоге проекта media
будет создан каталог для изображений, и изображение будет храниться в нем. Ниже приведен окончательный результат.
Теперь мы можем написать view для доступа к этим изображениям, для простоты давайте возьмем пример с одним изображением.
# Python program to view
# for displaying images
def display_hotel_images(request):
if request.method == 'GET':
# getting all the objects of hotel.
Hotels = Hotel.objects.all()
return render((request, 'display_hotel_images.html',
{'hotel_images' : Hotels}))
Образец шаблона файла HTML для отображения изображений.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hotel Images</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
</script>
</head>
<body>
{% for hotel in hotel_images %}
<div class="col-md-4">
{{ hotel.name }}
<img src="{{ hotel.hotel_Main_Img.url }}" class="img-responsive" style="width: 100%; float: left; margin-right: 10px;" />
</div>
{% endfor %}
</body>
</html>
Укажем путь в файле urls.py
# urls.py
path('hotel_images', display_hotel_images, name = 'hotel_images'),
Смотрим, что получилось