******************重点是思路*********
本文介绍如何使用 Django 框架和 Python 语言编写一个简单的照片浏览和上传网页。我们的网页可以实现以下功能:
我们需要定义一个照片模型,用于存储照片的名称、时间和类别。
views.py:
from django.shortcuts import render, redirect
from django.core.files.storage import FileSystemStorage
from django.utils import timezone
from .models import Photo
def home(request):
photos=Photo.objects.all()
return render(request, 'home.html', {'photos': photos})
def upload(request):
if request.method=='POST' and request.FILES['photo']:
photo=request.FILES['photo']
fs=FileSystemStorage()
filename=fs.save(photo.name, photo)
uploaded_file_url=fs.url(filename)
name=request.POST.get('name')
category=request.POST.get('category')
time=timezone.now()
photo=Photo(name=name, category=category, time=time, file_name=filename)
photo.save()
return redirect('home')
return render(request, 'upload.html')
使用了Django自带的FileSystemStorage来存储上传的照片文件。FileSystemStorage可以指定文件存储的路径,我们可以在settings.py中的MEDIA_ROOT中配置存储路径。例如,我们可以将存储路径设置为项目根目录下的一个名为media的文件夹:
MEDIA_URL='/media/'
MEDIA_ROOT=os.path.join(BASE_DIR, 'media')
上传的照片文件就会存储到项目根目录下的media文件夹中。在保存照片文件后,我们还需要将照片的名称、时间、类别存入MySQL数据库中。优化后的代码中,我们使用了Django的ORM来操作数据库。在Photo模型中,我们添加了一个file_name字段来存储照片文件的名称。
需要注意的是,为了使得优化后的代码能够正确地保存照片文件和数据库记录,我们还需要在项目的urls.py中添加一个urlpattern来映射media文件夹中的文件:
Django 是一个流行的 Python Web 开发框架,它提供了一系列工具和库,用于帮助开发人员构建高效、可扩展的 Web 应用程序。Django 的目标是让开发者能够以快速和简单的方式构建复杂的 Web 应用,通过提供许多预构建的组件和功能,如 ORM(对象关系映射)、表单处理、认证系统、管理界面等,从而降低了开发工作的复杂性。
今天,我们将会以一个示例为例,来演示关于图像上传的操作。
要顺利完成本教程,你需要具备以下条件:
首先,要在新项目中执行以下命令:
pip install django
安装完成后,我们现在开始执行以下步骤,以创建一个名为 xiaoYuGallery 的 Django 项目:
django-admin startproject xiaoYuGallery
cd xiaoYuGallery
py manage.py startapp demo
现在,我们需要打开位于项目目录下的 settings.py 文件,并在已安装应用程序列表 (INSTALLED_APPS) 中进行注册,以便将我们的 demo 应用程序纳入其中。请参考下面的示例代码:
INSTALLED_APPS=[
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'demo', # 这是我们新增的应用程序
]
确保在列表中添加 demo 这一行,并且位于其他 Django 内置应用程序的下方,这样可以确保我们的应用程序能够正确加载和运行。
当我们配置Django时,我们必须明确指定媒体文件的URL和存储位置。这可以通过设置MEDIA_URL和MEDIA_ROOT来完成。因此,在settings.py文件中,我们需要添加以下内容:
import os
MEDIA_URL='/media/'
MEDIA_ROOT=os.path.join(BASE_DIR, 'media')
为了确保用户在开发过程中能够上传图片,我们需要在项目级的urls.py文件中进行相应设置,以便进行测试。
from django.contrib import admin
from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
urlpatterns=[
path('admin/', admin.site.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
在models.py文件中,使用Django框架中的模型类来定义一个名为Image的模型。在这个模型中,我们定义了两个字段:
这个模型将允许我们在数据库中存储图片的标题和相应的图片文件,并且可以通过Django的ORM(对象关系映射)进行管理和操作。
from django.db import models
class Image(models.Model):
title=models.CharField(max_length=20)
photo=models.ImageField(upload_to='pics')
在admin.py 中我们定义了一个名为imageAdmin的类,它继承自admin.ModelAdmin。在这个类中,我们可以自定义模型在后台管理界面中的显示方式。在这个例子中,我们通过设置list_display属性,指定了在Image模型的列表页面中显示哪些字段。在这里,我们希望显示图片的标题和对应的图片文件。
最后,我们使用admin.site.register()函数将Image模型和imageAdmin类关联起来,这样就可以在后台管理界面中对Image模型进行管理,并且按照我们定义的方式进行显示。
from django.contrib import admin
from .models import Image
class imageAdmin(admin.ModelAdmin):
list_display=["title", "photo"]
admin.site.register(Image, imageAdmin)
在views.py ,我们添加这段代码,它是一个Django视图函数,用于处理用户请求并返回相应的网页内容。
from django.shortcuts import render
from .models import Image
# Create your views here.
def index(request):
data=Image.objects.all()
context={
'data' : data
}
return render(request,"display.html", context)
在display.html 里面渲染页面
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Demo Gallery</title>
</head>
<body class="container" style="padding-top: 5%;">
<div class="row">
{% for x in data %}
<div class="col-md-4">
<div class="card mb-4">
<img src="{{ x.photo.url }}" class="card-img-top" alt="{{ x.title }}">
<div class="card-body">
<h5 class="card-title">{{ x.title }}</h5>
</div>
</div>
</div>
{% endfor %}
</div>
<!-- Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
urls.py中配置URLs
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('', include('demo.urls')) # new
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
执行一下进行数据库迁移的命令:
py manage.py makemigrations:这个命令告诉 Django 你对模型进行了更改,并且需要将这些更改记录下来以便在数据库中进行更新。
py manage.py migrate:Django 会读取之前生成的迁移文件,并根据这些文件中的指令,在数据库中执行相应的更改,例如创建新的表、修改表结构或添加新的字段等。
py manage.py createsuperuser
当你运行这个命令时,Django 会提示你输入超级用户的用户名、电子邮件地址和密码。输入完毕后,Django 将会在数据库中创建一个新的超级用户,并使用你提供的信息设置其登录凭据。这个超级用户可以用来登录到 Django 的后台管理界面,进行网站管理和维护工作。
启动服务,一旦服务器启动,你就可以在浏览器中访问你的 Django 项目,并在开发环境中进行测试和调试。默认情况下,开发服务器会监听本地主机的 8000 端口,你可以通过在浏览器中输入 http://127.0.0.1:8000/ 或 http://localhost:8000/ 来访问你的网站。
py manage.py runserver
看下管理后台效果,点击add也会进行添加图片。
在这个示例中,我们将创建一个名为 forms.py 的文件,并在其中定义一个用于处理上传表单的类,将其与我们的 Image 模型相关联。这样做可以确保我们的代码结构清晰,易于维护和扩展。
from django import forms
from .models import Image
class ImageUploadForm(forms.ModelForm):
class Meta:
model=Image
fields=['title', 'photo']
在您的项目的templates文件夹中,您可以添加一个名为upload.html的文件。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Upload</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
form {
background-color: #fff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
width: 300px;
}
input[type="file"] {
margin-bottom: 10px;
}
button[type="submit"] {
background-color: #007bff;
color: #fff;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
button[type="submit"]:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit"> Upload Image </button>
</form>
</body>
</html>
在views.py更新下代码
def uploadView(request):
if request.method=='POST':
form=ImageUploadForm(request.POST, request.FILES)#如果请求方法为 POST,这一行创建一个 `ImageUploadForm` 的实例,通过将 `request.POST` 和 `request.FILES` 传递给它来填充表单数据。`request.POST` 包含用户通过 POST 方法提交的表单数据,而 `request.FILES` 包含用户上传的文件数据。
if form.is_valid(): #这一行检查表单数据是否有效,即是否通过了表单的验证。
form.save()#如果表单数据有效,这一行将保存表单数据到数据库中。
return redirect('index')
else:
form=ImageUploadForm()
return render(request, 'upload.html', {'form': form})
demo文件中更新下urls.py
from django.urls import path
from .import views
urlpatterns=[
path('', views.index, name='index'),
path('upload_image/', views.uploadView, name='upload_image')
]
我们来看下效果:
首页效果:
通过本文,我们深入了解了 Django 框架的一些基本概念和使用方法,以及如何利用 Django 构建一个简单的图像上传应用程序。从项目创建到环境配置,再到 admin 端图像处理和用户图片上传,我们逐步学习了如何利用 Django 提供的功能快速搭建 Web 应用。无论是对于初学者还是有一定经验的开发者,掌握 Django 都能够帮助我们更高效地开发出高质量的 Web 应用。希望本文能够为您提供一些帮助和启发,让您更加深入地了解 Django,并能够在实际项目中运用所学知识。
原文链接:https://juejin.cn/post/7367306429055598607
ue-quill-editor是个较为轻量级富文本,但是在使用vue-quill-editor我们会发现,vue-quill-editor默认插入图片是直接将图片转为base64再放入内容中,如果图片比较大的话,富文本的内容就会很大,而且也不方便我们处理。所以这里需要来重新定义图片上传功能,当我们选择图片后将图片上传服务器,服务器返回相应的图片链接,前端将图片链接插入到富文本的指定光标上位置,在提交富文本的内容的时候图片只是以图片地址提交。
我们重新写个简单的样式,用来上传图片是使用,默认隐藏(uploadimg=false),当我们点击上传图片图标时将其显示,所以这里我们要做的就是新增HTML和CSS并且重写toolbar中image的方法。
下面要做的就是重新定义image方法,在toolbar中的headers中 我们可以给对应的标签重新定义方法,这里我们要该的是image,当我们点击时显示我们新增的样式,也就是把uploadimg=false改成uploadimg=true,所以我们直接在headers中禁用quill内部上传图片,然后写个点击事件触发新事件。
#data toolbar:{ container: toolbarOptions, handlers: { 'image': function () { this.quill.format('image', false); //禁用quill内部上传图片 } } } #computed quill(){ let quill=this.$refs.BGEditor.quill return quill } # mounted img:{ var imgup=document.querySelector('.quill-editor .ql-image') imgup.onclick=()=>{ this.uploadimg=!this.uploadimg } }
思路:我们需要做的是点击“上传到服务器”按钮将我们选择的文件发送到后台,后台拿到我们的文件后进行存储并返回我们前端文件路径,前端拿到文件的存储路径,再把路径赋给光标所在的img标签中这样就可以在文中中看到我们上传的图片了。
首先要获取到上传的文件,这里我们用的是input标签,属性为file,所以这里我们没法用v-model来获取数据,这时我们需要用到$refs来定位获取,我们给input一个ref属性,然后通过let filename=this.$refs.imgfile.files[0]获取到文件对象。
注意事项:我们从前端发送文件给后端时是个文件,所以我们需要创建一个FormData对象来处理文件。
# HTML <div class="uploadImg" v-show="uploadimg" > <p>图像属性</p> <input type="file" ref="imgfile"> <span>支持.jpg .gif .png .bmp.jpeg,大小不超过5M</span></br> <button @click="upload">上传到服务器</button> </div> # models upload(){ let filename=this.$refs.imgfile.files[0] var formData=new FormData() formData.append("img",filename) this.$axios.post('http://127.0.0.1:8000/upload/',formData) .then(response=>{ console.log(response.data) }) },
model创建
我们需要创建一个文件的模型,这里用来存储文件的路径,并指定文件存储位置,我定义了一个简单的模型,只有文件名和文件路径,通过参数upload_to指定上传文件的保存目录,具体的操作可以参考:Django实战009:文件上传实现过程详解
class File(models.Model): name=models.CharField(max_length=100) file=models.ImageField(upload_to='image', null=True) def __str__(self): return self.name class Meta: db_table='file'
路由创建
我们需要给前台一个指定的路由来找到视图,我将upload指向了views.uploadfile,也就是uploadfile方法。
from django.conf.urls import url from user import views urlpatterns=[ # url(r'^login/$',views.login), # url(r'^register/$',views.register), url(r'^upload/$',views.uploadfile), ]
视图创建
现在我们需要一个视图(uploadfile)来接受前台发送的数据,通过 request.FILES.get('img')来获取文件对象,拿到文件名然后去数据库中查找该对象是否存在,如果存在我们直接返回该对象的路径,如果没有我们就新增并返回文件路径,这里我返回了一个code表示处理成功,返回一个url则是图片的文件路径。
def uploadfile(request): if request.method=="POST": fileName=request.FILES.get('img') imgname=fileName.name if not fileName: return HttpResponse('400') imgobj=models.File.objects.filter(name=imgname) if not imgobj: models.File.objects.update_or_create(name=imgname,file=fileName) imgurl=imgobj.first().file.url else: imgurl=imgobj.first().file.url info={'code': '200', 'url': imgurl} return JsonResponse(info) 注意事项:这里我们用的是filter而不是get,get是获取唯一值,当没有时就会报错,如果要用就用突然try包裹起来使用,用filter则是使用了查询集,没有则返回空。
首先我们先接受后台返回到的数据,通过code来判断数据是否处理成,如果失败则弹出“图片插入失败”提示,如果成功我们就将图片插入到光标所在位置即可。
*请认真填写需求信息,我们会在24小时内与您取得联系。