目录
上一篇主要是在编写相册管理系统前的铺垫,不知道的友友们可以去我主页上查看。
Django--在线相册管理系统(1)_橙子哈哈哈~的博客-CSDN博客
1、创建模板页
我们先在templates文件夹中右击新建一个base的网页文件
,用来做模板页,编写代码:
<!--模板页-->
<h1>在线相册信息管理系统</h1>
<a href="{% url 'index' %}">放回首页</a> | <a href="{% url 'look' 1 %}">浏览相册信息</a> | <a href="{% url 'add' %}">发布相册信息</a>
<hr/>
a标签里的为url:反向解析。
index为跳转页面,后面的数字为参数。
这样的好处会比较灵活,当某一个url配置的地址发生变化时,页面上使用反向解析生成地址的位置不需要发生变化。
在urls.py中添加路径:
path('',views.index,name="index"),
path('look/<int:pIndex>',views.look,name="look"),
path('add',views.add,name="add"),
在views.py中添加功能:
def index(request):
return render(request, "index.html") # 首页
def add(request):
return render(request, "addAlbum.html") # 添加页面
2、创建首页
还是在templates文件夹中创建一个index的网页文件,编写代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<center>
{% include "base.html" %} <!--加载模板并以标签内的参数渲染-->
<h1>首页</h1>
</center>
</body>
</html>
3、 添加错误提示页面
为的就是当操作错误时,就有一个提示作用。
在templates文件夹中创建一个info的网页文件,编写代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
{% include 'base.html' %}
<!-- 提示错误 -->
{% if info != null %}
<h3> {
{ info }} </h3>
{% if status == 200 %}
<a href="{% url 'look' 1 %}">放回浏览页</a>
{% elif status == 400 %}
<a href="javascript:history.go(-1)">返回上一页</a>
{% endif %}
<br/>
<br/>
{% endif %}
<!-- 上传和修改后的图片展示 -->
{% if image != null %}
<img src='/static/{
{image}}' width="500" height="330"/>
{% endif %}
<!-- 浏览图片 -->
{% if imageLook != null %}
<br/>
<a href="javascript:history.go(-1)">返回上一页</a>
<br/>
<br/>
<img src='/static/{
{ imageLook }}'/>
{% endif %}
</center>
</body>
</html>
这里用到了一些django标签的使用,不会的建议去补习一下基础知识,我就当大家都会这些标签的使用,不然挺麻烦的。
内容都在上面,包括与后面内容相联系的代码,现在看不懂的话,看到后面再回头看或许有新的体会。
4、增加相册信息
增删改查,就先从增开始吧。
4.1、编写网页部分
在templates文件夹中创建一个addAlbum的网页文件,编写代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>发布相册信息</title>
<script>
//当选择图片后,就会立即在下方显示选中图片
function setImagePreview(avalue) {
var docObj = document.getElementById("doc");
var imgObjPreview = document.getElementById("preview");
if (docObj.files && docObj.files[0]) {
imgObjPreview.style.width = '500px';
imgObjPreview.style.height = '330px';
imgObjPreview.src = window.URL.createObjectURL(docObj.files[0]);
}
return true;
}
</script>
</head>
<body>
<center>
{% include 'base.html' %}
<h2>添加相册信息</h2>
<form method="post" action="{% url 'addImage' %}" enctype="multipart/form-data">
{% csrf_token %} <!--防止跨站攻击的方法-->
<table width="400">
<tr>
<td>标题:</td>
<td><input type="text" name="title"></td>
</tr>
<tr>
<td>图片:</td>
<td><input type="file" name="pic" id="doc" onchange="setImagePreview(this)"/><br></td>
</tr>
</table>
<input type="submit" value="添加"> <input type="reset" value="重置">
</form>
<br/>
<img width="500" height="330" id="preview"/>
</center>
</body>
</html>
注意:
- 当Django在处理文件上传的时候,文件数据被保存在
request.FILES
- FILES中的每个键为<input type="file" name="" />中的name
- 注意:FILES只有在请求的方法为POST 且提交的<form>带有enctype="multipart/form-data" 的情况下才会包含数据。
- 否则,FILES 将为一个空的类似于字典的对象
4.2、编写后端部分
在urls.py文件中加上一个路径:
path('addImage',views.addImage,name="addImage"),
在views.py文件中添加功能:
from PIL import Image
from ablumapp.models import Album
def addImage(request):
try:
# 网页传输内容的解析就不多说了,不懂的可以去百度下相关内容
fileTitle = request.POST['title']
fileImage = request.FILES.get("pic", None)
fileTtpe = fileImage.name.split('.').pop() # 获得图片的后缀名,知晓是什么类型
if fileImage == None:
content = {"info": "暂无上传文件!","status":400}
return render(request, "info.html", content)
if fileTitle == '':
content = {"info": "请输入标题!","status":400}
return render(request, "info.html", content)
if fileTtpe.lower() != "jpg" and fileTtpe.lower() != "png" and fileTtpe.lower() != "jpeg":
content = {"info": "请选择图片文件!","status":400}
return render(request, "info.html", content)
# 判断标题是否与数据库中重复
mod = Album.objects # ablumapp.models下的Album类
ulist = mod.filter(title=fileTitle)
if len(ulist) == 0:
filename = request.POST['title'] + "." + fileTtpe # 组合后的文件名
# 之前创建的static文件夹起到用途了,就是用它来存放上传的图片
Imagefile = open("./static/" + filename, "wb+")
for chuck in fileImage.chunks():
Imagefile.write(chuck)
Imagefile.close()
# 执行图片缩放
im = Image.open("./static/" + filename)
im.thumbnail((75, 75))
im.save("./static/small/s_" + filename, None) # 记得在static文件夹中创建一个small文件夹,用来存放缩放后的图片。
# 添加记录
ob = Album()
ob.title = fileTitle
ob.type = fileTtpe
ob.save()
content = {"info": "上传成功!", "image": filename,"status":200}
else:
content = {"info": "标题重复,请重新输入","status":400}
except:
content = {"info": "上传失败!","status":400}
return render(request, "info.html", content)
render方法的作用:
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。
通俗的讲就是把context的内容, 加载进templates中定义的文件, 并通过浏览器渲染呈现。
5、查看相册信息
5.1、编写网页部分
在templates文件夹中创建一个lookAlbum的网页文件,编写代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>浏览相册信息</title>
<script>
//自定义执行信息删除提示判断,参数uu是成功的删除url地址
function doDel(url){
if(confirm("确定要删除吗?")){
//网页跳转
window.location=url;
}
}
</script>
</head>
<body>
<center>
{% include 'base.html' %}
<h3>浏览相册图片信息</h3>
<form method="get" action="{% url 'look' 1 %}">
标题:<input type="text" name="keyword"/>
<input type="submit" value="搜索"/>
</form>
<br/>
<table width="800" border="1">
<tr>
<th>ID号</th>
<th>标题</th>
<th>图片</th>
<th>时间</th>
<th>操作</th>
</tr>
{% for album in AlbumList %}
<tr>
<td>{
{ album.id }}</td>
<td>{
{ album.title }}</td>
<td style="text-align:center;">
<a href="{% url 'lookBigImage' album.id %}"><img src='/static/small/s_{
{ album.title }}.{
{ album.type }}'/></a>
<!--点击后放大比例查看图片-->
</td>
<td>{
{ album.add_time|date:'Y-m-d' }}</td>
<td>
<a href="{% url 'updata' album.id %}">编辑</a>
<a href="javascript:doDel('{% url 'del' album.id %}');">删除</a>
</td>
</tr>
{% endfor %}
</table>
<br/>
<!--分页功能-->
<!--像这种{% url 'look' pIndex|add:-1 %},后面跟着的是django的过滤器,可以自行去了解下,就不做细讲-->
<a href="{% url 'look' pIndex|add:-1 %}{
{mywhere}}">上一页</a>
{% for p in pageList %}
{% if pIndex == p %}
<a href="{% url 'look' p %}{
{mywhere}}" style="color:red;">{
{ p }}</a>
{% else %}
<a href="{% url 'look' p %}{
{mywhere}}" >{
{ p }}</a>
{% endif %}
{% endfor %}
<a href="{% url 'look' pIndex|add:1 %}{
{mywhere}}">下一页</a>
<br/>
<br/>
<br/>
</center>
</body>
</html>
对应分页内容看不懂的,可以看接下来的后端代码,结合起来看。
5.2、编写后端代码
在urls.py中添加:
path('look/<int:pIndex>',views.look,name="look"),
在views.py中添加:
def look(request, pIndex=1):
try:
kw = request.GET.get('keyword', None)
mywhere = ""
if kw != None:
ulist = Album.objects.filter(title__contains=kw)
mywhere = "?keyword=" + kw
else:
ulist = Album.objects.all()
p = Paginator(ulist, 5) # 返回分页对象,参数为列表数据,每面数据的条数
# 设置页号边界
if pIndex < 1:
pIndex = 1
if pIndex >= p.num_pages: # 页面总数
pIndex = p.num_pages
# 下标以1开始,如果提供的页码不存在,抛出InvalidPage异常。这个方法比较方便快捷的分页,输入第几页,就会放回对应页数的数据,在这里进行的筛选。
list = p.page(pIndex)
content = {"AlbumList": list, "pIndex": pIndex, "pageList": p.page_range, "mywhere": mywhere}
return render(request, "lookAlbum.html", content)
except:
content = {"info": "没有找到用户信息","status":400}
return render(request, "info.html", content)
给讲下分页思路:
当点击搜索后,会将输入的内容(kw)发送到后端,设置mywhere = "?keyword=" + kw
,对数据库所有标题进行模糊查找,放入一个列表中,用方法取出对应页的数据然后放回到页面中。简答讲下,要知道网址?后面的就是get类型的访问参数,(http://127.0.0.1:8000/look/1?keyword=3),类似这种,具体看代码吧。
6、修改相册信息
6.1、编写网页部分
在templates文件夹中创建一个updata的网页文件,编写代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>修改相册信息</title>
<script>
// 和添加操作一样,缩减大小立即显示
function setImagePreview(avalue) {
var docObj = document.getElementById("doc");
var imgObjPreview = document.getElementById("preview");
if (docObj.files && docObj.files[0]) {
//火狐下,直接设img属性
imgObjPreview.style.width = '500px';
imgObjPreview.style.height = '330px';
//imgObjPreview.src = docObj.files[0].getAsDataURL();
//火狐7以上版本不能用上面的getAsDataURL()方式获取,需要一下方式
imgObjPreview.src = window.URL.createObjectURL(docObj.files[0]);
}
return true;
}
</script>
</head>
<body>
<center>
{% include 'base.html' %}
<h2>修改相册信息</h2>
<form method="post" action="{% url 'doupdata' id %}" enctype="multipart/form-data">
{% csrf_token %}
<table width="400">
<tr>
<td>标题:</td>
<td><input type="text" name="title" value="{
{ title }}"></td>
</tr>
<tr>
<td>图片:</td>
<td><input type="file" name="pic" id="doc" onchange="setImagePreview(this)"/><br></td>
</tr>
</table>
<input type="submit" value="编辑"> <input type="reset" value="重置">
</form>
<br/>
<br/>
<img src='/static/{
{ title }}.{
{ type }}' width="500" height="330" id="preview"/>
</center>
</body>
</html>
6.2、编写后端部分
在urls.py中添加:
path('updata/<int:uid>',views.updata,name="updata"), # 在浏览页点击修改后的路由路径
path('doupdata/<int:uid>',views.doupdata,name="doupdata"), # 执行修改命令的功能
在views.py中添加:
# 将信息记录并跳转到修改页面
def updata(request, uid):
# 查询
mod = Album.objects
objects = mod.filter(id=uid)[0]
content = {"id": objects.id, "title": objects.title, "type": objects.type, "time": objects.add_time}
return render(request, "updata.html", content)
# 修改功能
def doupdata(request, uid):
try:
# 判断标题是否重复
mod = Album.objects
ulist = mod.filter(title=request.POST['title']).exclude(id=uid)
if len(ulist) == 0:
fileImage = request.FILES.get("pic", None)
if fileImage == None:
content = {"info": "暂无上传文件!","status":400}
return render(request, "info.html", content)
fileType = fileImage.name.split('.').pop()
if fileType.lower() != "jpg" and fileType.lower() != "png" and fileType.lower() != "jpeg":
content = {"info": "请选择图片文件!","status":400}
return render(request, "info.html", content)
ob = Album.objects.get(id=uid)
oldTitle = ob.title + "." + ob.type
# 删除旧照片
os.remove("./static/small/s_" + oldTitle)
os.remove("./static/" + oldTitle)
# 修改标题
ob.title = request.POST['title']
# 修改类型
ob.type = fileType
filename = request.POST['title'] + "." + fileType
# 保存图片到本地
Imagefile = open("./static/" + filename, "wb+")
for chuck in fileImage.chunks():
Imagefile.write(chuck)
Imagefile.close()
# 执行图片缩放并保存到本地
im = Image.open("./static/" + filename)
im.thumbnail((75, 75))
im.save("./static/small/s_" + filename, None)
ob.save()
content = {"info": "修改成功!","status":200}
else:
content = {"info": "标题重复,请重新输入","status":400}
except:
content = {"info": "修改失败!","status":400}
return render(request, "info.html", content)
这里应该都知道吧,对应部分都有注释。
7、删除相册信息
网页部分与第5步结合,添加了删除提示,以防误点:
7.1、编写后端部分
在urls.py中添加:
path('delete/<int:uid>',views.delete,name="del"),
在views.py中添加:
def delete(request, uid):
try:
ob = Album.objects.get(id=uid)
oldTitle = ob.title + "." + ob.type
# 删除旧照片
os.remove("./static/small/s_" + oldTitle)
os.remove("./static/" + oldTitle)
# 删除数据库信息
ob.delete()
content = {"info": "删除成功!","status":200}
except:
content = {"info": "删除失败!","status":400}
return render(request, "info.html", content)
8、附加:点击图片变大
网页代码请看第5点,图片标签被a标签包含了。
8.1、编写后端部分
在urls.py中添加:
path('lookBigImage/<int:uid>',views.lookBigImage,name="lookBigImage"),
在views.py中添加:
def lookBigImage(request, uid):
try:
ob = Album.objects.get(id=uid)
image = ob.title + "." + ob.type
content = {"imageLook": image}
return render(request, "info.html", content)
except:
content = {"info": "查看失败","status":400}
return render(request, "info.html", content)
好了,这个在线相册管理系统就写完啦,运行看看效果吧,如果哪里有看不懂的地方就在评论区中留言或私信我哦!
未经允许,请勿转载!