Python在Django中上传图片
在大多数网站中,我们经常处理媒体数据,如图片、文件等。在django中,我们可以借助ImageField这个模型字段来处理图片。
在这篇文章中,我们在一个名为image_upload的示例项目中创建了image_app应用程序。
第一步是在settings.py文件中添加以下代码。
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
MEDIA_ROOT是服务器路径,用于在计算机中存储文件。
MEDIA_URL是浏览器通过Http访问文件的参考URL。
在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的例子应该是这样的,我们创建了一个酒店模型,它由酒店名称和它的图像组成。
在这个项目中,我们从用户那里获取酒店名称和它的图像,用于酒店预订网站。
# models.py
class Hotel(models.Model):
name = models.CharField(max_length=50)
hotel_Main_Img = models.ImageField(upload_to='images/')
这里upload_to将指定图片应该存放在哪个目录下,默认情况下,django会在媒体目录下创建一个目录,当我们上传图片时,该目录会自动创建。不需要明确创建媒体目录。
我们必须在image_app下创建一个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来包围每个标题和字段。
在image_app下的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中。如果它是有效的保存到数据库中,并重定向到表示成功上传图片的成功网址。如果方法不是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)
现在进行迁移并运行服务器。
当我们在浏览器中点击URL时,以这种方式看起来。
上传图片后,它将显示成功。
现在在项目目录下将创建媒体目录,在该目录下将创建图像目录,图像将被存储在该目录下。这里是最终的结果。
存储在数据库中的最终输出
现在我们可以写一个视图来访问这些图片,为了简单起见,我们以一张图片为例,它也适用于许多图片。
# 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文件中插入url路径
# urls.py
path('hotel_images', display_hotel_images, name = 'hotel_images'),
下面是我们试图访问图片时在浏览器上的最终视图。
Hotel Image