- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章python设计微型小说网站(基于Django+Bootstrap框架)由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
1、项目背景:
为了回顾关于django的文件上传和分页功能,打算写一个微型的小说网站练练手。花了一个下午的时间,写了个小项目,发现其中其实遇到了许多问题,不过大部分通过debug之后就解决了,其他部分通过阅读了Pagination插件以及Bootstrap-FileInput插件的官方文档.
2、详细设计:
省去小说网站的用户模块的功能,小说网站主要的功能就是上传文件,在线阅读小说。针对这两个功能, 。
主要用到dajngo内置的Pagination模块,以及选择一个上传文件插件即可。因为用的是Bootsrap前端框架,所以就选择了Bootsrap比较多人用的FileInput插件.
大致的流程:
3、合适的工具:
Django内置的Pagination实现分页功能,这个不用多说,用Django做web开发分页功能都会用到.
Bootstrap本身自带upload file文件上传插件太丑了,加上功能也不够完善。所以选择了Bootstrap FileInput插件.
版本选择:
4、代码详解:
首先代码主要分为两块,一块为文件上传后,接收文件对象,保存到指定的目录下;第二块为读取txt文本文件内容,分页展示到前端页面.
首先讲讲文件上传的代码,主要涉及到前端的bootstrap-fileinputt插件。该插件将简单的HTML文件输入转换为高级文件选择器控件。对于不支持JQuery或Javascript的浏览器,将有助于回退到正常的HTML文件输入.
以上这段是官方的自我介绍,说说我个人感受吧。首先这个插件支持批量上传,异步上传等功能,简化大部分JS逻辑方面的代码,具体只要跟着官方的API文档看一看,修改一些参数即可。其次,对于上传时会显示一个进度条,用于显示上传的完成度,这样直观反映了完成度.
bootstrap-fileinput的github地址:
https://github.com/kartik-v/bootstrap-fileinput 。
bootstrap-fileinput的官方文档地址:
http://plugins.krajee.com/file-input 。
bootstrap-fileinput的官方DEMO:
http://plugins.krajee.com/file-basic-usage-demo 。
4.1、文件上传 。
HTML代码:
<div dir=rtl class="file-loading"> <input id="input-b8" name="input-b8" multiple type="file"></div>
JS代码:
$(document).ready( function() {$("#input-b8").fileinput({ rtl: true, uploadUrl: '/file_receive/', dropZoneEnabled: false, showPreview: false, allowedFileExtensions: ['txt'], initialPreviewConfig: []});});
代码说明:
fileinput()方法里面传入的是一个json数据,里面有很多个属性,每个数值代表初始化上传控件时的特性,如果没有设置的属性则按照控件的默认属性设置。简单说下里面几个属性的设置:uploadUrl:上传文件地址;dropZoneEnabled:是否显示拖曳区域;showPreview:是否显示预览区域;allowedFileExtensions:允许上传的文件格式.
后台代码 。
def file_receive(request): # 接收File-Input空间传送的文件 if request.method == 'POST': file = request.FILES['input-b8'] file_path = "static/books/"+file.name with open(file_path,"wb") as f: for chunk in file.chunks(): f.write(chunk) return JsonResponse({'status':'success'})
代码说明:
以上是后台接收文件对象并且保存的代码。我这边省略判断上传文件大小的方法,感兴趣的可以在with open()中添加判断。最后接收文件后,会返回给前端一个json数据,前端插件接收到返回的JSON数据才会确定是否上传文件成功,bootstrap Fileinput才会先Done状态.
拓展:
这里有点需要注意的就是,后台接收上传的文件,虽然是通过POST的方式上传,但是不能通过request.POST["filename"]或者request.POST.get("filename","None")两种方式来访问.
而是需要用另外一种方式:
request.FILES["filename"]或者request.FILES.get("filename","None") 。
接下来已经得到文件对象,需要把在内存中的文件写入到硬盘中。读取文件的几个方法和属性:
4.2、异步更新已上传的文件列表 。
HTML代码:
<div style="padding-top: 20px"> <table id="book_list" class="table table-striped table-bordered table-hover"> <tr> <th>上传书籍</th> <th>上传时间</th> <th>文件大小</th> <th>操作</th> </tr> {% for book in objects %} <tr> <td>{{ book.name}}</td> <td>{{ book.book_time }}</td> <td>{{ book.book_size }}</td> <td><a href="/book_read/?book_name={{ book.name }}" rel="external nofollow" >阅读</a> <a href="/book_del/?book_name={{ book.name }}" rel="external nofollow" >删除</a></td> </tr> {% endfor %} </table></div>
JS代码:
$("#input-b8").on('fileuploaded',function(){ console.log('success'); $.get('/book_update/',function(data){ var book_html ="<tr>\n" + "<th>上传书" + "籍</th>" + "<th>上传时间</th>" + "<th>文件大小</th>" + "<th>操作</th>"+ "</tr>"; console.log(data); for (var i in data){ book_html += "<tr><td>"+ data[i]['name']+"</td>" + "<td>"+data[i]['book_time']+"</td>" + "<td>"+data[i]['book_size']+"</td>" + "<td><a href=\"/book_read/?book_name="+data[i]['name']+"\">阅读</a>"+ "<a href=\"/book_del/?book_name="+data[i]['name']+"\">删除</a></td>"+ "</tr>" } $("#book_list").html(book_html) console.log(book_html) });});
代码说明:
$("#input-b8").on('fileuploaded',function(){})这个方法时在上传完文件后进行回调事件的函数;就是指上传一个文件成功后就会调用该方法;所以我将异步更新上传文件列表的代码放在这个回调事件中。当每个文件上传后,就会请求后台,查询指定目录下的文件列表,生成json格式的数据返回前台,前台再通过遍历的形式拿到其中的数据,进行展示,具体效果如下:
后台代码 。
def book_list(): # 获取books目录下的书籍 file_list = [] filedir_path = "static/books/" list_file = os.listdir(filedir_path) for book in list_file: book_info = {} book_path = filedir_path + book book_info['name'] = book book_info['timestamp'] = os.path.getctime(book_path) book_info['book_time'] = time_format(book_info['timestamp']) book_info['book_size'] = os.path.getsize(book_path) file_list.append(book_info) books = sorted(file_list,key= lambda x:x['timestamp'],reverse=True) return books def time_format(timestamp): # 格式化时间戳成指定的时间 time_struct = time.localtime(timestamp) time_string = time.strftime('%Y-%m-%d %H:%M',time_struct) return time_string
代码说明:
代码其实很简单,主要是对通过os模块获取静态目录static下的books目录下的文件列表,然后在获取每个文件的时间戳,通过列表推导式,按时间戳为key值进行逆向排序.
4.3、文章分页模块 。
HTML代码:
<div class="header text-center "> <a href="/index/" rel="external nofollow" style="float: left;"> <i class="fa fa-home fa-2x" aria-hidden="true">Home</i> </a> <h3>{{ book_name }}</h3></div><div class="col-md-12 col-sm-offset-1 main"> {% for content in book_content %} <span>{{ content }}</span> {% endfor %}</div><div class="pagination"> <div class="col-md-4 "> {% if book_content.has_previous %} <i class="fa fa-arrow-left" aria-hidden="true"> <a href="?book_name={{ book_name }}&page={{ book_content.previous_page_number }}" rel="external nofollow" > 上一页 </a> </i> {% endif %} </div> <div class="col-md-4 "> <h5> 第{{ book_content.number }}页/共{{ book_content.paginator.num_pages }}页 </h5> </div> {% if book_content.has_next %} <div class="col-md-4 "> <a href="?book_name={{book_name}}&page={{ book_content.next_page_number }}" rel="external nofollow" > 下一页 </a> <i class="fa fa-arrow-right" aria-hidden="true"> </i> </div> {% endif %}</div>
JS代码:
def book_read(request): # 获取上传书籍的内容 if request.method == 'GET': book_name = request.GET['book_name'] # 书籍名称 file_path = "static/books/" + book_name # 书籍路径 with open(file_path,encoding='gbk', errors='ignore') as f: book_contents = f.readlines() paginator = Paginator(book_contents, 50) try: page = int(request.GET['page']) # 页码 book_content = paginator.page(page) except Exception as e: book_content = paginator.page(1) return render_to_response('book.html',{'book_content': book_content, 'book_name': book_name})
代码说明:
读取文件的所有行,保存在一个列表中(list),每行作为一个元素。然后实例化一个Paginator对象,并且在实例化中传入一个需要分页的对象列表,以及一页包含多少个数据。再从接收前端传送过来的页码,取特定页码的数据,再传回前端.
拓展:
1、分页功能有Django内置的Paginator类提供的,该类位于django/core/paginator,需要用的地方导入即可: from django.core.paginator improt Paginator 。
2、read()、readline()、readlines()方法的区别:
三者都是读取文件内容:
3、Paginator对象操作:
实例化对象:
book_list = [1,2,3,4,5,6,7,8]book_content = Paginator(book_list,3)
取特定页的数据 。
content = book_content.page(2)
查特定页当前页码数:
content.number
查分页后的总页数 。
content.num_pages
查询某一页是否有上一页或者查询上一页页码:
content.has_previous()content.previous_page_number()
查询某一页是否有下一页或者查询下一页页码:
content.has_next()content.next_page_number()
感兴趣的同学可以上GitHub上,项目代码的地址:
https://github.com/libuliduobuqiuqiu/noval_test 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持.
原文链接:https://blog.51cto.com/mbb97/2363772 。
最后此篇关于python设计微型小说网站(基于Django+Bootstrap框架)的文章就讲到这里了,如果你想了解更多关于python设计微型小说网站(基于Django+Bootstrap框架)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我需要开发一个简单的网站,我通常使用 bootstrap CSS 框架,但是我想使用 Gumbyn,它允许我使用 16 列而不是 12 列。 我想知道是否: 我可以轻松地改变绿色吗? 如何使用固定布局
这个问题在这里已经有了答案: 关闭 13 年前。 与直接编写 PHP 代码相比,使用 PHP 框架有哪些优点/缺点?
我开发了一个 Spring/JPA 应用程序:服务、存储库和域层即将完成。 唯一缺少的层是网络层。我正在考虑将 Playframework 2.0 用于 Web 层,但我不确定是否可以在我的 Play
我现有的 struts Web 应用程序具有单点登录功能。然后我将使用 spring 框架创建一个不同的 Web 应用程序。然后想要使用从 struts 应用程序登录的用户来链接新的 spring 应
我首先使用Spark框架和ORMLite处理网页上表单提交的数据,在提交中文字符时看到了unicode问题。我首先想到问题可能是由于ORMLite,因为我的MySQL数据库的字符集已设置为使用utf8
我有一个使用 .Net 4.5 功能的模块,我们的应用程序也适用于 XP 用户。所以我正在考虑将这个 .net 4.5 依赖模块移动到单独的项目中。我怎样才能有一个解决方案,其中有两个项目针对不同的版
我知道这是一个非常笼统的问题,但我想我并不是真的在寻找明确的答案。作为 PHP 框架的新手,我很难理解它。 Javascript 框架,尤其是带有 UI 扩展的框架,似乎通过将 JS 代码与设计分开来
我需要收集一些关于现有 ORM 解决方案的信息。 请随意编写任何编程语言。 你能谈谈你用过的最好的 ORM 框架吗?为什么它比其他的更好? 最佳答案 我使用了 NHibernate 和 Entity
除了 Apple 的 SDK 之外,还有什么强大的 iPhone 框架可供开始开发?有没有可以加快开发时间的方法? 最佳答案 此类框架最大的是Three20 。 Facebook 和许多其他公司都使用
有人可以启发我使用 NodeJS 的 Web 框架吗?我最近开始从免费代码营学习express js,虽然一切进展顺利,但我对express到底是什么感到困惑。是全栈框架吗?纯粹是为了后端吗?我发现您
您可以推荐哪种 Ajax 框架/工具包来构建使用 struts 的 Web 应用程序的 GUI? 最佳答案 我会说你的 AJAX/javascript 库选择应该较少取决于你的后端是如何实现的,而更多
我有生成以下错误的 python 代码: objc[36554]: Class TKApplication is implemented in both /Library/Frameworks/Tk.
首先,很抱歉,如果我问的问题很明显,因为我没有编程背景,那我去吧: 我想运行一系列测试场景并在背景部分声明了几个变量(我打印它们以仔细检查它们是否已正确声明),第一个是整数,另外两个字符串为你可以看到
在我们承担的一个项目中,我们正在寻找一个视频捕获和录制库。我们的基础工作(基于 google 搜索)表明 vlc (libvlc)、ffmpeg (libavcodec) 和 gstreamer 是三
我试过没有运气的情况下寻找某种功能来杀死/中断Play中的正常工作!框架。 我想念什么吗?还是玩了!实际没有添加此功能? 最佳答案 Java stop类中没有像Thread方法那样的东西,由于种种原因
我们希望在我们的系统中保留所有重大事件的记录。例如,在数据库可能存储当前用户状态的地方,事件日志应记录对该状态的所有更改以及更改发生的时间。 事件记录工具应该尽可能接近于事件引发器的零开销,应该容纳结
那里有 ActionScript 2.0/3.0 的测试框架列表吗? 最佳答案 2010-05-18 更新 由于这篇文章有点旧,而且我刚刚收到了赞成票,因此可能值得提供一些更新的信息,这样人们就不会追
我有一个巨大的 numpy 数组列表(一维),它们是不同事件的时间序列。每个点都有一个标签,我想根据其标签对 numpy 数组进行窗口化。我的标签是 0、1 和 2。每个窗口都有一个固定的大小 M。
我是 Play 的新手!并编写了我的第一个应用程序。这个应用程序有一组它依赖的 URL,从 XML 响应中提取数据并返回有效的 URL。 此应用程序需要在不同的环境(Dev、Staging 和 Pro
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
我是一名优秀的程序员,十分优秀!