I. Project Background

Just to review django
File uploadand
paging, decided to write a mini novel website to practice. I spent an afternoon writing a small project and found that there were many problems in it, but most of them were solved after passing the debug, while the rest were read
Pagination plug-inAs well as
The Bootstrap – the FileInput plug-inThe official document of the.

Ii. Detailed design:

Omit the function of the user module of the novel website, the main function of the novel website is
Upload a file.
Reading novels online. For these two functions,


The main use of dajngo built-in Pagination module, and select a file upload plug-in. Because the Bootsrap front-end framework is used, so choose Bootsrap more people use FileInput plug-in.



General process:

  • On the home page, you can choose to upload local TXT files to the server. Then, the list of uploaded TXT files will be asynchronously updated on the home page.
  • And you can choose to read or delete the operation. Reading will jump to another page, background will read the text file, and paging operation, back to the front end. That’s the main process. Next, the Pagination and FileInput plug-ins and core code.

Three, the right tools:

Djangos built-in Pagination enables Pagination, which goes without saying, as well as Pagination for web development.


Bootstrap comes with its own upload file plug-in, which is ugly and not fully functional. So the Bootstrap FileInput plugin was chosen.

Version selection:

  • Python 3.6.6
  • Django = = 2.1.7
  • The Bootstrap v4.3.1
  • The bootstrap – the fileinput v4.5.2

Four, code details:

First of all, the code is mainly divided into two parts, one is
After the file is uploaded, the system receives the file object and saves the file to a specified directory.The second piece of
Read TXT text file content, paging display to the front page.


First talk about file upload code, mainly related to the front end
bootstrap-fileinputtThe plug-in. This plug-in converts simple HTML file input to
Advanced file selector control. For browsers that do not support JQuery or Javascript, it will help to fall back to normal HTML file input.




The above paragraph is the official self-introduction, tell me my personal feelings. First of all, this plug-in supports batch upload, asynchronous upload and other functions, simplify most of the JS logic aspects of the code, as long as the official API documentation to take a look, modify some parameters can be. Secondly, a progress bar will be displayed for uploading to show the completion of the upload, which directly reflects the completion degree.

Bootstrap-fileinput github address:


Github.com/kartik-v/bo…


Bootstrap-fileinput official file address:


plugins.krajee.com/file-input


Bootstrap-fileinput:


Plugins.krajee.com/file-basic-…

4.1 File upload


HTML code:

<div dir=rtl

class

=

“file-loading”

>

<input id=”input-b8″ name=”input-b8″ multiple type=”file”></div>

JS code:

$(

document

).ready(

function()

{$(

“#input-b8”

).fileinput({

rtl

:

true

.

uploadUrl

:

‘/file_receive/’

.

dropZoneEnabled

:

false

.

showPreview

:

false

.

allowedFileExtensions

: [

‘txt’

].

initialPreviewConfig

: []}); });

Code description:



The fileinput ()The method is passed a
jsonData, there are a lot of properties, each value represents the initial upload control when the characteristics, if no set of properties will be set according to the control’s default properties. A brief description of the Settings of several properties inside:
uploadUrl:Upload file address;
dropZoneEnabled:Whether the drag area is displayed;
ShowPreview:Whether to display the preview area;
AllowedFileExtensions:Format of the file that can be uploaded.


The background code

def file_receive(request):
# receive files sent in file-input space

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’

})

Code description:


This is the background to receive the file object and save the code. I have omitted the method to determine the size of the uploaded file. If you are interested, you can add the method in with open(). When the file is finally received, a JSON data is returned to the front-end and the front-end plug-in receives the returned JSON data
The JSON dataWill determine whether the file has been uploaded successfully,
bootstrap FileinputTo be first
DoneState.

Development:

Request.POST[“filename”] or request.post. get(“filename”,”None”).


It needs to be done in a different way:



request.FILES[“filename”]or
request.FILES.get(“filename”,”None”)


Now that you have the file object, you need to write the file in memory to the hard disk. Several methods and properties for reading files:

  • Filename.read () : Reads the entire uploaded data from a file. This method is only suitable for small files
  • Filename.chunks () : Returns files in chunks and iterates through the for loop to write large files in chunks to the server
  • Filename.multiple_chunks (): This method returns True if the filename file is larger than 2.5m, False otherwise. This method can be used to determine whether to use method 1 or 2.

4.2 Asynchronously update the list of uploaded files


HTML code:

<div style=”padding-top: 20px”>

<table id=”book_list” class=”table table-striped table-bordered table-hover”>

<tr>

<th>

Upload the books

</th>

<th>

Upload time

</th>

<th>

The file size

</th>

<th>

operation

</th>

</tr>

{% for book in objects %}

<tr>

<td>

{{ book.name}}

</td>

<td>

{{ book.book_time }}

</td>

<td>

{{ book.book_size }}

</td>

<td>

reading

</a>

delete

</a>

</td>

</tr>

{% endfor %}

</table>

</div>


JS code:

$(

“#input-b8”

).on(

‘fileuploaded’

.

function()

{

console

.log(

‘success’

); $.get(

‘/book_update/’

.

function(data)

{

var

book_html =

“<tr>\n”

+

” Upload book”

+

“Book < / th >”

+

” Upload time ”

+

” File size ”

+

Following the “< th > < / th >”

+

“</tr>”

;

console

.log(data);

for

(

var

i

in

data){ book_html +=

“<tr><td>”

+ data[

‘name’

] +

“</td>”

+

“<td>”

+data[

‘book_time’

] +

“</td>”

+

“<td>”

+data[

‘book_size’

] +

“</td>”

+

+data[

‘name’

] +

Read “\” > < / a >”

+

+data[

‘name’

] +

Delete “/” > < / a > < / td >”

+

“</tr>”

} $(

“#book_list”

).html(book_html)

console

.log(book_html) }); });

Code description:



$(“#input-b8”).on(‘fileuploaded’,function(){})This method is a function that calls back the event after uploading the file; This method is called when a file is uploaded successfully. So I will
Update the list of uploaded files asynchronouslyThe code is placed in the callback event. When each file uploaded, will request the background, query the specified directory under the file list, generated
Json formatIs returned to the front desk, the front desk through the form of traversal to get the data, the specific effect is as follows:



The background code

def book_list():
Get books from 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):
Format the timestamp to the specified time

time_struct = time.localtime(timestamp) time_string = time.strftime(

‘%Y-%m-%d %H:%M’

,time_struct)

return

time_string

Code description:


The code is actually very simple, mainly through
OS moduleGet the static directory under static
Books directoryThen, after obtaining the timestamp of each file, reverse sort the key value by timestamp through the list derivation.

4.3 Article paging module


HTML code:

<div class=”header text-center “>

<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”>

The previous page

</a>

</i>

{% endif %}

</div>

<div class=”col-md-4 “>

<h5>

Page {{book_content.number}} / total {{book_content.paginator. Num_pages}} page

</h5>

</div>

{% if book_content.has_next %}

<div class=”col-md-4 “>

The next page

</a>

<i class=”fa fa-arrow-right” aria-hidden=”true”>

</i>

</div>

{% endif %}

</div>


JS code:

def book_read(request):
# Get the content of the uploaded book

if

request.method ==

‘GET’

: book_name = request.GET[

‘book_name’

]

# Book title

file_path =

“static/books/”

+ book_name

# Book path

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’

])

# 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})

Code description:


Read all lines of the file in a list, each line as an element. And then instantiate one
Paginator objectAnd pass in the instantiation a list of objects to page and how many data a page contains. Again from
Receive the page number sent from the front endRetrieves the data for a specific page number and passes it back to the front end

Development:

Paginator is provided by Django’s built-in Paginator class, which is located in Django/Core/Paginator and will be imported wherever you need to use it:


from django.core.paginator improt Paginator

Read (), readline(), readlines()


All three read the contents of the file:


Read ([size]): Reads size bytes from the current position, or until the end of the file if the method does not have size. Returns a string object.


Readline () : Method calls that read a file one line at a time and return a string.


Readlines (): Reads all lines of the entire file, stored in a list, each line as an element

Paginator Instantiates the object. Book_list = [1,2,3,4,5,6,7,8]book_content = Paginator(book_list,3) take data for specific page content = book_content.page Num_pages Queries whether a page has a previous page or queries the number of previous pages: Content.has_previous ()content.previous_page_number() queries whether a page has a next page or queries the next page number: content.has_next()content.next_page_number()

More technical information can be obtained from itheimaGZ