1

I generated a csv file through my code, and after generation, it goes to the path of my project, my project called sample, so the file path sample/output.csv.. I added a function for the download and I called this function inside the my main function ( home), but the download is not working, what I'm doing wrong?

def save_file(request):
   # data = open(os.path.join(settings.PROJECT_PATH,'data/table.csv'),'r').read()
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename=output1.csv'
    return response


def home(request):
    if request.method=="POST":
        img = UploadForm(request.POST, request.FILES)
        if img.is_valid():
            logging.warning('Watch out!')  # will print a message to the console
           # paramFile = request.FILES['pic']
            paramFile =io.TextIOWrapper(request.FILES['pic'].file)
            portfolio1 = csv.DictReader(paramFile)
            print(type(paramFile))
            users = []
            # users = [row["BASE_NAME"] for row in csv_file]
            # users = zip(*csv_file)
            #  users = [row[0] for row in csv_file]

           # for row in portfolio1:
             #   users.append(row)
            users = [row["BASE_NAME"] for row in portfolio1]
            print(len(users))

            my_list = users
            vectorizer = CountVectorizer()
            dtm = vectorizer.fit_transform(my_list)

            lsa = TruncatedSVD(n_components=100)
            dtm_lsa = lsa.fit_transform(dtm)
            dtm_lsa = Normalizer(copy=False).fit_transform(dtm_lsa)
            similarity = np.asarray(numpy.asmatrix(dtm_lsa) * numpy.asmatrix(dtm_lsa).T)
            # print(1-similarity)
            k = len(my_list)
            dist1 = np.subtract(np.ones((k, k), dtype=np.float), similarity)
            # dist1=similarity
            # dist1.astype(float)
            #print(dist1)
            # print(cosine_similarity(tfidf_matrix[3:4], tfidf_matrix))
            # float dist = 1 - similarity;
            data2 = np.asarray(dist1)
            arr_3d = data2.reshape((1, k, k))
            # arr_3d= 1- arr_3d
            #print(arr_3d)

            no_clus = 40
            for i in range(len(arr_3d)):
                # print (i+1910)
                # km = AgglomerativeClustering(n_clusters=no_clus, linkage='ward').fit(arr_3d[i])
                km = AgglomerativeClustering(n_clusters=no_clus, linkage='average').fit(arr_3d[i])
                # km = AgglomerativeClustering(n_clusters=no_clus, linkage='complete').fit(arr_3d[i])
                # km = MeanShift()
                # km = KMeans(n_clusters=no_clus, init='k-means++')
                # km = MeanShift()
                #  km = km.fit(arr_3d[i])
                # print km
                labels = km.labels_

            csvfile = r'C:\users\A6B0SZZ\PycharmProjects\sample\media\images\export.csv'

            csv_input = pd.read_csv(csvfile, encoding='latin-1')
            csv_input['cluster_ID'] = labels
            csv_input['BASE_NAME'] = my_list
            csv_input.to_csv('output.csv', index=False)
            clus_groups = list()
            for j in range(no_clus):
                # print(" cluster no %i:%s" % (j, [my_list[i] for i, x in enumerate(labels) if x == j]))
                list_of_ints = ([my_list[i] for i, x in enumerate(labels) if x == j])
                clus_groups.append('  '.join(list_of_ints))
            vectorizer = CountVectorizer()
            dtm = vectorizer.fit_transform(my_list)

            lsa = TruncatedSVD(n_components=100)
            dtm_lsa = lsa.fit_transform(dtm)
            dtm_lsa = Normalizer(copy=False).fit_transform(dtm_lsa)
            similarity = np.asarray(numpy.asmatrix(dtm_lsa) * numpy.asmatrix(dtm_lsa).T)
            k = len(my_list)
            dist1 = 1 - similarity

            data2 = np.asarray(dist1)
            arr_3d = data2.reshape((1, k, k))
            # arr_3d= 1- arr_3d

            no_clus = 5
            for i in range(len(arr_3d)):
                # print (i+1910)
                # km = AgglomerativeClustering(n_clusters=no_clus, linkage='ward').fit(arr_3d[i])
                # km = AgglomerativeClustering(n_clusters=no_clus, linkage='average').fit(arr_3d[i])
                # km = AgglomerativeClustering(n_clusters=no_clus, linkage='complete').fit(arr_3d[i])
                km = KMeans(n_clusters=5, init='k-means++')
                km = km.fit(arr_3d[i])
                # print km
                labels2 = km.labels_
                # error = km.inertia_
                print(labels2)

            labels = labels.tolist()
            labels2 = labels2.tolist()
            # new=list()


            csv_input = pd.read_csv(r'C:\users\A6B0SZZ\PycharmProjects\sample\output.csv',encoding='latin-1')
            labels1 = csv_input['cluster_ID']
            new_list = []
            for k in labels1:
                new_list.append(labels2[k])  # lookup the value in list2 at the index given by list1

            print(new_list)
            print(len(new_list))
            csv_input = pd.read_csv(r'C:\users\A6B0SZZ\PycharmProjects\sample\output.csv',encoding='latin-1')
            csv_input['cluster_ID'] = labels
            csv_input['BASE_NAME'] = my_list
            csv_input['User_Map'] = new_list
            csv_input.to_csv('output1.csv', index=False)

           # my_list = portfolio
            save_file(request)
           # return HttpResponseRedirect(reverse('portfolio'))
            return render(request, 'home.html', {'labels': labels})
    else:
        img=UploadForm()
    images=Upload.objects.all()
    return render(request,'home.html',{'form':img,'images':images})

And my home.html is:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div style="padding:40px;margin:40px;border:1px solid #ccc">
    <h1>Upload the CSV File to Run the Algorithm on:</h1>
    <form action="#" method="post" enctype="multipart/form-data">
        {% csrf_token %} {{form}}
         <input type="submit" value="Upload" />
    </form>
    {% for img in images %}
        {{forloop.counter}}.<a href="{{ img.pic.url }}">{{ img.pic.name }}</a>
        ({{img.upload_date}})<hr />
    {% endfor %}

</div>
</body>
</html>

Url.py:

from django.conf.urls import url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    url(r'^upload/$', 'uploader.views.home', name='labels'),
    url(r'^admin/', admin.site.urls),
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Edit, my function now is: but still not working:

def save_file(request):
   # data = open(os.path.join(settings.PROJECT_PATH,'data/table.csv'),'r').read()
   # file_path = r'C:\users\A6B0SZZ\PycharmProjects\sample\output1.csv'
   # fsock = open(file_path, "r")
    fsock= pd.read_csv(r'C:\users\A6B0SZZ\PycharmProjects\sample\output1.csv', encoding='latin-1')
    response = HttpResponse(fsock, content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename=output1.csv'
    return response
Lelo
  • 347
  • 3
  • 16
  • Edit, I put print statements inside save_file function, and they are printing fine! – Lelo Jun 14 '16 at 16:32

3 Answers3

2

For the main issue with your download not working, please take a look at this answer because the first argument for your HttpResponse should be your data to actually send.

Now, also you should do is look at interacting with the storage classes & MEDIA_ROOT.

This will enable your project to work locally or remotely on a server. Looking at what you've posted I'll assume your settings.py contains something like MEDIA_ROOT = 'C:\users\A6B0SZZ\PycharmProjects\sample\media'

You might want to consider some more generic, reusable paths in your settings.py (depending on how your project is structured, but this is what I have);

SETTINGS_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_DIR = os.path.abspath(os.path.join(SETTINGS_DIR, '../'))
BASE_DIR = os.path.abspath(os.path.join(PROJECT_DIR, '../'))

STATIC_ROOT = os.path.join(BASE_DIR, 'static-collection')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

Some good reading here would be Managing Files which takes you over the various ways to create files & access their paths.

Community
  • 1
  • 1
markwalker_
  • 12,078
  • 7
  • 62
  • 99
  • what I have in setting.py is : MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/' – Lelo Jun 14 '16 at 15:37
  • That's a good point, I'm reading the file path alot in my home function, how to replace this C:\users\A6B0SZZ\PycharmProjects\sample\output.csv'? I'm assuming this won't work once it's converted to the server or operated by other pc – Lelo Jun 14 '16 at 15:47
  • Can you use the answer my question the way similar to the answer in the link you mentioned, I tried but didn't work either, how to specify the rows there? – Lelo Jun 14 '16 at 17:14
0

If you want to send the file to the browser that way, the file has to be un a directory directly accessible by webserver. In most cases, the folder where all Python code is stored is not accesible.

Try to put the file in a directory accesible by webserver. Another way of sending the file is reading it through Python and sending it inline, like the user is doing in this question: django return file over HttpResponse - file is not served correctly

Community
  • 1
  • 1
arnau
  • 410
  • 5
  • 12
  • I passed it now as the question you mentioned, however, it's still not working, maybe I'm not calling the function right inside the home function? – Lelo Jun 14 '16 at 15:56
  • What error are you getting? File not found? Please try to add some more information to be able to resolve the issue. – arnau Jun 15 '16 at 17:38
0

I ended it up using FILEwrapper:

def send_file(request):

  filename = settings.MEDIA_ROOT +'/'+ 'output1.csv'
  #filename= r"C:\Users\A6B0SZZ\PycharmProjects\sample\media\output1.csv"
  download_name ="output1.csv"
  wrapper      = FileWrapper(open(filename))
  response     = HttpResponse(wrapper,content_type='text/csv')
  response['Content-Disposition'] = "attachment; filename=%s"%download_name
  return response
Lelo
  • 347
  • 3
  • 16