Django--在线相册管理系统(2)

目录

1、创建模板页

2、创建首页

3、 添加错误提示页面

4、增加相册信息

4.1、编写网页部分

4.2、编写后端部分

 5、查看相册信息

5.1、编写网页部分

5.2、编写后端代码

6、修改相册信息

6.1、编写网页部分

6.2、编写后端部分

7、删除相册信息

7.1、编写后端部分

8、附加:点击图片变大

8.1、编写后端部分


上一篇主要是在编写相册管理系统前的铺垫,不知道的友友们可以去我主页上查看。

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配置的地址发生变化时,页面上使用反向解析生成地址的位置不需要发生变化。

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="添加">&nbsp;&nbsp;<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>&nbsp;
        {% for p in pageList %}
            {% if pIndex == p %}
                &nbsp;&nbsp;<a href="{% url 'look' p %}{
   
   {mywhere}}" style="color:red;">{
   
   { p }}</a>
            {% else %}
                &nbsp;&nbsp;<a href="{% url 'look' p %}{
   
   {mywhere}}" >{
   
   { p }}</a>
            {% endif %}
        {% endfor %}
        &nbsp;&nbsp;<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="编辑">&nbsp;&nbsp;<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)

好了,这个在线相册管理系统就写完啦,运行看看效果吧,如果哪里有看不懂的地方就在评论区中留言或私信我哦!

未经允许,请勿转载!

猜你喜欢

转载自blog.csdn.net/qq_56966336/article/details/122972160