[Answered ]-How to read or write an uploaded file from FileField model in Django 3.0+?

1👍

I asked my professor how to access the file and he told me that this method worked for him to read the uploaded file:

content = open(self.files.path, encoding="ISO-8859-1").read()

Now as for my original request to first read and then find the total words, different words and most common words of the book that I uploaded(it worked for .txt files for me), here are my Models, Views and html files:

Models:

from django.db import models
from string import punctuation, whitespace

from authors.models import Author

class Book(models.Model):
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    book_name = models.CharField(max_length=50)
    genre = models.CharField(max_length=50)
    files = models.FileField(upload_to='books/files/')

    def __str__(self):
        return self.book_name()

    def total_words(self):
        d = dict()
        content = open(self.files.path, encoding="ISO-8859-1").read()

        words = content.split()
        for word in words:
            word = word.strip(punctuation + whitespace)
            word = word.lower()
            d[word] = d.get(word, 0) + 1

        return sum(d.values())

    def different_words(self):
        d = dict()
        content = open(self.files.path, encoding="ISO-8859-1").read()
        words = content.split()
        for word in words:
            word = word.strip(punctuation + whitespace + '“”')
            word = word.lower()
            d[word] = d.get(word, 0) + 1

        return len(d)

    def most_common_words(self, num=10):
        d = dict()
        content = open(self.files.path, encoding="ISO-8859-1").read()
        words = content.split()
        for word in words:
            word = word.strip(punctuation + whitespace + '“”')
            word = word.lower()
            d[word] = d.get(word, 0) + 1

        t = []
        for word, freq in d.items():
            t.append((freq, word))
        t.sort(reverse=True)
    return t[:num]

Views:

def detail(request, pk):
    book = get_object_or_404(Book, pk=pk)
    instance = Book.objects.get(pk=pk)
    instance.total_words()
    instance.different_words()
    instance.most_common_words()

    return render(request, 'books/detail.html', context={'book': book, 'instance': instance})

detail.html :

{% extends 'base.html' %}

{% block title %} {{ book.book_name }} {% endblock %}

{% block content %}
    <p>Book title: {{ book.book_name }}</p>
    <p>Genre: {{ book.genre }}</p>
    <p>Author:
        <a href="{% url 'authors:detail' book.author.pk %}">{{ book.author.full_name }}</a>

    </p>
    <p><b>Total words in book:</b></p>
    <p>{{ instance.total_words }}</p>
    <p><b>Different words in book:</b></p>
    <p>{{ instance.different_words }}</p>
    <p><b>Most common words in book:</b></p>
    <p>{{ instance.most_common_words }}</p>


    <p><button type="button"><a href="{{ book.files.url }}" target="_blank">Shkarko</a></button></p>
{% endblock %}

Thank you to the people that tried helping me on this question!

0👍

Am Assuming if your file is a PDF you can write your code in this manner to allow readability. reading a fileis pretty simple and you can work around it with this example !

  • Django view function returns the FileResponse.

  • You need to import it from django.http before using.

  • Open file in the ‘rb’ mode using Python open() method.

  • You have to provide the complete or relative path to your PDF file.

  • FileResponse content-type should be ‘application/pdf’.

  • Make sure, you have a PDF file present in your project static directory.

  • It is not good practice to hardcode the file path. File path of the static
    files can vary while deploying production build.

from django.http import FileResponse
import os
 
def show_file(request):
    filepath = os.path.join('static', 'sample.pdf')
    return FileResponse(open(filepath, 'rb'), content_type='application/pdf')

As you can also write your view as a classview to allow users read the book from your detail view

class DisplayPdfView(BaseDetailView):
    def get(self, request, *args, **kwargs):
        objkey = self.kwargs.get('pk', None) #1
        pdf = get_object_or_404(Pdf, pk=objkey) #2
        fname = pdf.filename() #3
        path = os.path.join(settings.MEDIA_ROOT, 'docs\\' + fname)#4
        response = FileResponse(open(path, 'rb'), content_type="application/pdf")
        response["Content-Disposition"] = "filename={}".format(fname)
        return response
👤Godda

Leave a comment