Django : trying to call the get method after the post method for a class view

Question:

I made a classview to upload the files in an azure blobstorage, shows a table of the history of the uploaded files and allows to display them in the right part of the page.

I have a problem when a file is uploaded by the POST method, the file selected earlier is not executed by the GET method, so the content is not loaded in the context and cannot be displayed in the template.

I thought of two solutions. The first one is calling the GET method at the end of the POST method. However, this doesn’t work and it doesn’t seem to be efficient according to the stackoverflow documentation. That’s why I left it as a comment at the end of the POST method. The other solution is a redirect to this same classview, however this does not work : ValueError: The view documents.views.view didn't return an HttpResponse object. It returned None instead.

How can I execute this get method without copying the lines of code in the post method.

views.py

class DocumentUpload(FormView) :
    model   = TblDocument
    template_name = 'documents/documents.html'
    form_class = FilesForm


    def get_context_data(self, *args, **kwargs):
        # Call the base implementation first to get a context

        context = super(DocumentUpload, self).get_context_data(*args, **kwargs)
        context['object_list'] = TblDocument.objects.all()

        return context

    def get(self, request, *args, **kwargs):

        # WE LOAD THE CONTEXT
        context = self.get_context_data(**kwargs)

        # DOWLOAD AND ENCODED THE CONTENT
        fileID  = request.GET.get('fileID', 2)
        file            = TblDocument.objects.get(Id=fileID)
        url             = file.Url
        extension       = file.Format
        blob_name       = url.split("/")[-1]
        blob_content    = AzureBlob().download_from_blob(blob_name=blob_name)
        encodedstring   = base64.b64encode(blob_content.readall())
        
        # CHARGE THE CONTEXT
        context['fileID']         = fileID
        context['extension']        = extension
        context["encodedstring"]    = str(encodedstring)[1:].replace("'","")

        return render(request, self.template_name, context)

    def post(self, request, *args, **kwargs):

        # WE LOAD THE CONTEXT
        context = self.get_context_data(**kwargs)

        # WE GET THE LIST OF FILES FROM THE POST METHOD
        form = self.form_class(request.POST, request.FILES)
        files_selected = request.FILES.getlist('Filename') # create a list of files

        if form.is_valid():

            for file in files_selected :

                # DEFINE THE DATA OF THE FILE
                file = FileDefinitionBeforeUpload(file=file).file_information()

                # GET THE CONTENT OF THE FILE
                content = file.read()
                file_io =  BytesIO(content)

                # THE UPLOAD TO THE BLOB
                AzureBlobFile   = AzureBlob()
                blob_client     = AzureBlobFile.blob_client(blob_name= file.name)
                blob_client.upload_blob(data=file_io)

                user = self.request.session.get('user')

                newfile = TblDocument(  User                = user.get('email'), 
                                        Filename            = file.name, 
                                        Filenamebeforeindex = file.previous_name, 
                                        Sizefile            = file.size, 
                                        Format              = file.extension,
                                        # ID_Customer     = id_contrat, 
                                        Url                 = blob_client.url)
                newfile.save()
        else :

            form = FilesForm()

        # CHARGE THE CONTEXT FOR THE TEMPLATE
        context['form'] = form

        # self.get(request, *args, **kwargs)

        # return render(request, self.template_name, context)
        return redirect(DocumentUpload.as_view())

html

<!DOCTYPE html>
<html lang="en">

{%  load static %} 

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- Boxicons CSS -->
    <link   href='https://unpkg.com/[email protected]/css/boxicons.min.css' 
            rel='stylesheet'>
    <link rel="stylesheet" href="{% static 'style.css' %}">

</head>

<body>

    {{ encodedstring | json_script:'fileDATA' }} 
    {{ extension | json_script:'fileEXT'}}
    
    <div class="upload-app">
        <div class="upload-in">
            <h2>Upload</h2>

            <form method="post" enctype="multipart/form-data">
                
                {% csrf_token %}
                {{ form.as_p }}

                <button type="submit" id="submitupload">Upload</button>
            </form>
        
            <div class="fileselect">
                <p>Selected files :</p>
                    <div id="fileselect"></div>
            </div>     
        </div> 
        <div class="listfiles">

            <h2>Files Uploaded</h2>

            <table id="customers">
                <tr>
                    <th>Filename</th>
                    <th>Date</th>
                    <th>Size</th>
                    <th>Actions</th>
                </tr>

                {% for file in object_list %}
                <tr>
                    <td>{{ file.Filenamebeforeindex }}</td>
                    <td>{{ file.Timestamp | date:'d.m.Y H:i'}}</td>
                    <td>{{ file.Sizefile | filesizeformat}}</td>
                    <td class="iconsColumn">
                        <a href="">
                            <i class='bx bxs-download'></i>
                        </a>
                        <a href="?fileID={{ file.Id }}">
                            <i class='bx bxs-file-pdf' ></i>
                        </a>
                    </td>>
                </tr>
                {% endfor %}

            </table>
    </div>

    <div id="pdfdisplay">

    </div>

urls.py

from django.urls import path
from documents.views import *

urlpatterns = [ 
    path('documents/', DocumentUpload.as_view(), name="documents"),
   ]
Asked By: Goncalves

||

Answers:

You can not work with DocumentUpload.as_view() since this constructs a function, and each time a different function object, hence the error.

You can use the name of the view:

urlpatterns = [
    path('documents/', DocumentUpload.as_view(), name='documents'),
]

since that is here 'document‘, we can redirect with:

return redirect('document')

or if there is an app_name in the urls.py, with:

return redirect('app_name:document')
Answered By: Willem Van Onsem
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.