Excel files not showing on Heroku web app - python

I have a django backed website on Heroku and every time I try to view/download the upload excel files after uploading them on the Heroku website I get this error:
Not Found: The requested URL /excel_files/<file> was not found on this server.
Here is my views.py:
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from .forms import UploadForm
from django.conf import settings
import os
import openpyxl, re
def index(request):
"""The home page which generates the donor list html page"""
if request.method != 'POST':
form = UploadForm()
else:
form = UploadForm(request.POST or None, request.FILES or None)
if form.is_valid():
form.save()
file = request.FILES['fileobj'].name
file_corrected = file.replace(" ", "_")
path = os.path.join(settings.MEDIA_ROOT, file_corrected)
wb = openpyxl.load_workbook(path)
sheet = wb.get_sheet_by_name('Sheet1')
text_file = open('upload/templates/upload/donor_list.html', 'w')
html1 = "{% extends 'upload/base.html' %}" + "\n" + "{% block header %}" + "\n" + " <h1>Donor List</h1>" + "\n" + "{% endblock header %}" + "\n" + "{% block content %}" + "\n"
html2 = "{% endblock content %}"
text_file.write(html1)
for rowNum in range(1, sheet.max_row + 1):
firstName = str(sheet.cell(row=rowNum, column=1).value)
if firstName == "None":
firstName = "\n"
lastName = str(sheet.cell(row=rowNum, column=2).value)
addNum = re.compile(r'\d(\d)*')
addressNumber1 = addNum.search(str(sheet.cell(row=rowNum, column=3).value))
if addressNumber1 is None:
addressNumber = ""
if addressNumber1 is not None:
addressNumber = addressNumber1.group(0)
donate = str(sheet.cell(row=rowNum, column=4).value)
donate = "$" + donate
if donate == "$None":
donate = ""
date = str(sheet.cell(row=rowNum, column=7).value)
year = date[2:4]
if year == "ne":
year = ""
if firstName == "\n" and lastName != "None":
firstName = str(sheet.cell(row=rowNum, column=2).value)
lastName = str(sheet.cell(row=rowNum, column=3).value)
addressNumber1 = addNum.search(str(sheet.cell(row=rowNum, column=4).value))
addressNumber = addressNumber1.group(0)
donate = str(sheet.cell(row=rowNum, column=5).value)
donate = "$" + donate
date = str(sheet.cell(row=rowNum, column=8).value)
year = date[2:4]
if firstName is "_" or lastName is "Anonymous":
text_file.write(""" <p>{} (Mr./Ms.) {} {} {}.</p>""".format(addressNumber, lastName, donate, year) + '\n')
else:
text_file.write(""" <p>{} {} {} {}.</p>""".format(addressNumber, firstName, donate, year) + '\n')
text_file.write(html2)
text_file.close()
return donor_list(request)
context = {'form': form}
return render(request, 'upload/index.html', context)
def instructions(request):
"""The how-to for file uploading"""
return render(request, 'upload/instructions.html')
def donor_list(request):
"""Webpage with the donor list after upload"""
return render(request, 'upload/donor_list.html')
and here is my settings.py as it relates to the Heroku website:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
# Heroku settings
cwd = os.getcwd()
if cwd == '/app' or cwd[:4] == '/tmp':
import dj_database_url
DATABASES = {
'default': dj_database_url.config(default='postgres://localhost')
}
# Honor the "X-Forwarded_Proto' header for request.is.secure().
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# Allow only Heroku to host the project
ALLOWED_HOSTS = ['WEBSITE_URL_HERE']
DEBUG = False
# Static asset configuration
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
STATIC_ROOT = 'staticfiles'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
MEDIA_ROOT = os.path.join(BASE_DIR, 'excel_files')
MEDIA_URL = '/excel_files/'
Notice that my views.py after upload displays the excel file as text using openpyxl module, but i find it odd that I can't seem to access these excel files on my Heroku admin page; they are listed but I can't download them as I described above. Beginner friendly answers are greatly appreciated.

You must not upload files to the filesystem on Heroku. As the documentation explains, the filesystem is ephemeral and is not shared between dynos. Anything uploaded will only be seen by the dyno that created it, and will be completely lost when that dunno restarts.
You must use a permanent store, for example S3.

Related

Auto download not working for Django FileResponse

I need to let the Django auto download the generated file.
Tried all different solutions online, none of them works.
Views.py
def validate(request):
if request.method == 'POST':
filename = request.POST.get('source_file')
file_path = os.path.join(settings.MEDIA_ROOT, 'SourceFiles', filename)
region = request.POST.get('region')
product_type = request.POST.get('product_type')
result = validateSource.delay(file_path, region, product_type)
output_filepath, log_filepath = result.get()
if os.path.exists(output_filepath) and os.path.exists(log_filepath):
zip_filename = zipFiles([output_filepath, log_filepath], filename)
zip_filepath = os.path.join(settings.MEDIA_ROOT, zip_filename)
response = FileResponse(open(zip_filepath, 'rb'), as_attachment=True)
return response
raise Http404
Template: code for the form POST.
$(document).on('submit', '#productForm', function(e){
e.preventDefault();
var inputFilePath = document.getElementById('sourceFileInput').files.item(0).name;
$.ajax({
method: 'POST',
url: 'validate/',
data: {
source_file: inputFilePath,
region: $("#Region-choice").val(),
product_type: $("#Product-type").val()}
})
.done(function(){
document.getElementById('lblStatus').innerHTML = "Result: <br/>"
document.getElementById('lblStatusContent').innerHTML = "Success!"
})
.fail(function(req, textStatus, errorThrown) {
document.getElementById('lblStatus').innerHTML = "Result: <br/>"
alert("Something went wrong!:" + textStatus + ' ' + errorThrown )
});
});
});
It's not possible to download files to your computer via an ajax (XHR) request. So you need to redirect the user actually (setting window.location) to a view that downloads the file. Or you can add as a result of the successful POST a button the current page so the user can download the file. In any case, you need to move the file download to a different view so a standard GET request can fetch it.
But your code to return the file in Django (using FileResponse) is correct.
There's also an explanation with an alternative way of doing it here
def validate(request):
if request.method == 'POST':
filename = request.POST.get('source_file')
file_path = os.path.join(settings.MEDIA_ROOT, 'SourceFiles', filename)
region = request.POST.get('region')
product_type = request.POST.get('product_type')
result = validateSource.delay(file_path, region, product_type)
output_filepath, log_filepath = result.get()
if os.path.exists(output_filepath) and os.path.exists(log_filepath):
zip_filename = zipFiles([output_filepath, log_filepath], filename)
zip_filepath = os.path.join(settings.MEDIA_ROOT, zip_filename)
with open(zip_filepath, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/force-download")
response['Content-Disposition'] = 'attachment; filename=' + os.path.basename(zip_filepath)
return response
raise Http404

ExtractionError: Can't extract file(s) to egg cache

I'm developing my app on Windows with GAE, but the below error message was shown.
C:\Python27\Lib\site-packages
Perhaps your account does not have write access to this directory? You can
change the cache directory by setting the PYTHON_EGG_CACHE environment
variable to point to an accessible directory.
So I checked some post in this site and I found some articles but I could not understand it. My understanding is that I need to create cache directory with write access in home directory, but I did not understand where "home directory" is.
Also in other post, I found the answer saying This approach solved my issue. I did uninstall pyyaml using pip and then installed it with easy_install -z pyyaml
Which approach is correct?
import webapp2
import os
import jinja2
import cloudstorage
import mimetypes
from PIL import Image
from google.appengine.ext import ndb
from google.appengine.ext import blobstore
from google.appengine.api import users
from google.appengine.api import app_identity
from google.appengine.api import images
from models import Note
from models import CheckListItem
from models import NoteFile
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
images_formats = {
'0':'image/png',
'1':'image/jpeg',
'2':'image/webp',
'-1':'image/bmp',
'-2':'image/gif',
'-3':'image/ico',
'-4':'image/tiff',
}
class MainHandler(webapp2.RequestHandler):
def get(self):
user = users.get_current_user()
if user is not None:
logout_url = users.create_logout_url(self.request.uri)
template_context = {
'user': user.nickname(),
'logout_url' : logout_url,
}
template = jinja_env.get_template('main.html')
self.response.out.write(template.render(template_context))
else:
login_url = users.create_login_url(self.request.uri)
self.redirect(login_url)
def post(self):
user = users.get_current_user()
if user is None:
self.error(401)
bucket_name = app_identity.get_default_gcs_bucket_name()
uploaded_file = self.request.POST.get('uploaded_file')
file_name = getattr(uploaded_file,'filename',None)
file_content = getattr(uploaded_file,'file',None)
real_path = ''
if file_name and file_content:
content_t = mimetypes.guess_type(file_name)[0]
real_path = '/' + bucket_name + '/' + user.user_id() + "/" + file_name
with cloudstorage.open(real_path,'w',content_type=content_t,options={'x-goog-acl':'public-read'}) as f:
f.write(file_content.read())
self._create_note(user, file_name, real_path)
logout_url = users.create_logout_url(self.request.uri)
template_context = {
'user':user.nickname(),
'logout_url': logout_url,
}
self.response.out.write(self._render_template('main.html',template_context))
def _render_template(self,template_name,context=None):
if context is None:
context = {}
user = users.get_current_user()
ancestor_key = ndb.Key("User",user.nickname())
qry = Note.owner_query(ancestor_key)
context['notes'] = qry.fetch()
template = jinja_env.get_template(template_name)
return template.render(context)
#ndb.transactional
def _create_note(self,user,file_name,file_path):
note = Note(parent=ndb.Key("User", user.nickname()), title=self.request.get('title'), content=self.request.get('content'))
note.put()
item_titles = self.request.get('checklist_items').split(',')
for item_title in item_titles:
item = CheckListItem(parent=note.key, title=item_title)
item.put()
note.checklist_items.append(item.key)
if file_name and file_path:
url, thumbnail_url = self._get_urls_for(file_name)
f = NoteFile(parent=note.key, name=file_name, url=url,thumbnail_url=thumbnail_url,full_path=file_path)
f.put()
note.files.append(f.key)
note.put()
def _get_urls_for(self,file_name):
user = users.get_current_user()
if user is None:
return
bucket_name = app_identity.get_default_gcs_bucket_name()
path = '/' + bucket_name + '/' + user.user_id() + '/' + file_name
real_path = '/gs' + path
key = blobstore.create_gs_key(real_path)
try:
url = images.get_serving_url(key, size=0)
thumbnail_url = images.get_serving_url(key,size=150,crop=True)
except images.TransformationError,images.NotImageError:
url = "http://storage.googleapis.com{}".format(path)
thumbnail_url = None
return url,thumbnail_url
class MediaHandler(webapp2.RequestHandler):
def get(self,file_name):
user = users.get_current_user()
bucket_name = app_identity.get_default_gcs_bucket_name()
content_t = mimetypes.guess_type(file_name)[0]
real_path = '/' + bucket_name + '/' + user.user_id() + '/' + file_name
try:
with cloudstorage.open(real_path,'r')as f:
self.response.headers.add_header('Content-Type',content_t)
self.response.out.write(f.read())
except cloudstorage.errors.NotFoundError:
self.abort(404)
class ShrinkHandler(webapp2.RequestHandler):
def _shrink_note(self,note):
for file_key in note.files:
file = file_key.get() # this is the same as "file.get().url" in html file. we add the comment.
try:
with cloudstorage.open(file.full_path) as f:
image = images.Image(f.read())
image.resize(640)
new_image_data = image.execute_transforms()
content_t = images_format.get(str(image.format))
with cloudstorage.open(file.full_path,'w',content_type=content_t) as f:
f.write(new_image_data)
except images.NotImageError:
pass
def get(self):
user = users.get_current_user()
if user is None:
login_url = users.create_login_url(self.request.url)
return self.redirect(login_url)
ancestor_key = ndb.Key("User",user.nickname())
notes = Note.owner_query(ancestor_key).fetch()
for note in notes:
self._shrink_note(note)
self.response.write('Done.')
app = webapp2.WSGIApplication([
(r'/', MainHandler),
(r'/media/(?P<file_name>[\w.]{0,256})',MediaHandler),
(r'/shrink',ShrinkHandler)
], debug=True)
It looks like you're developing a standard env GAE app but you're attempting to install third party libraries in (and use them from) your local system's site packages. This won't work.
You need to install the third party libraries in your app's library directory (i.e. using -t <your_lib_dir> option for pip install, for which you shouldn't need special permissions. See also:
Using third-party libraries.
No module named warnings when starting GAE inside virtualenv locally

django python file storage

I would like to upload a file, parse it to .txt and then store it in the disk via a django application. I've tried quiet a few things that didn't work. First I want to make the storage work. Here's my code. I would appreciate any help.
Index.html
<form name='F' action='AjoutTelechargement' method='POST'
enctype='multipart/form-data'>
{% csrf_token %}
<input type="file" name="filedir" style="color:white" size="100" >
<input type="submit" class="btn .btn-ajouter btn-xl page-scroll"
value="Ajouter" />
<script type="text/javascript" src="/media/js/jquery-1.10.2.min.js">
</script>
<script>
function myFun() {
$.get('AjoutTelechargement/'
, "value":"get_the_value_from_web"}
, function(ret) {
return ret;
});
}
models.py
from django.db import models
from django.core.files.storage import FileSystemStorage
key_store = FileSystemStorage(location='myFiles/')
class FileUpload(models.Model):
file = models.FileField(storage=key_store, upload_to='myFiles/%Y-%m-%d',
blank=False, null=False)
urls.py
from django.conf.urls import url
from django.contrib import admin
from omicCV import views as omicCV_views
from blog import views as blog_views
urlpatterns = [
url(r'^$', omicCV_views.index),
url(r'^admin', admin.site.urls),
url(r'^AjoutTelechargement$', blog_views.AjoutTelechargement),
]
views.py
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
from .models import FileUpload
#csrf_exempt
def AjoutTelechargement(request):
if request.method == 'POST':
form = FileUpload(request.POST, request.FILES)
form.save()
return HttpResponse("done!")
I am trying to parse the uploaded pdf files to txt:
def AjoutTelechargement(request):
if request.method == 'POST' and request.FILES['filedir']:
filedir = request.FILES['filedir']
fs = FileSystemStorage(location='myFiles/')
for filename in filedir:
path=filename
if b"pdf" in filename:
print("repère2")
head, tail = os.path.split(path)
var = b"\\"
tail = tail.replace(b".pdf", b".txt")
name = head + var + tail
content = ""
pdf = PyPDF2.PdfFileReader(path, bool('rb'))
for i in range(0, pdf.getNumPages()):
content += pdf.getPage(i).extractText()
print(strftime("%H:%M:%S"), " pdf -> txt ")
with (name, 'a') as f:
text_file_doc = {"file_name": "test_file_name.txt",
"contents": f.write(content.encode('ascii', 'replace').decode('UTF-8'))}
fs.save(filedir.name, text_file_doc)
return HttpResponse("done!")
return HttpResponse("undone")
But got this error in this line: pdf = PyPDF2.PdfFileReader(path, bool('rb'))
Exception Value:
'bytes' object has no attribute 'seek'
Exception Location: C:\Users\RAHMA\omicroneCV\lib\site-packages\PyPDF2\pdf.py in read, line 1689

download csv file from my project path django

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}}.{{ img.pic.name }}
({{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
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.
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
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

My Django Based Project Sporadically Stops Loading Views (Django 1.6) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have a problem that seems to pop up randomly throughout the entire web app I have been working on.
My app will be moving along just fine and then, when moving from one view to another, the page will start to load but then continue on loading indefinitely. I can go back refresh and then continue on through the same view like there was absolutely no problem at all. When this happens the rest of code in my view still runs just fine, but the page just continues loading without producing any kind of Http Response.
Like I said I have tried to remove parts of my project to figure out where the issue may lie. The issue started to happen near the time I migrated my database to using South although I really am not sure if/how the two would be intertwined. Even if you have an idea of what might be causing the issue please respond I would greatly appreciate any help or even a general direction to go in.
urls.py
from django.conf.urls import patterns, url
from BucketList import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^stats/$', views.index_stats, name='index stats'),
url(r'^item/(?P<id>\w+)/comment/', views.add_item_comment, name = 'add item comments'),
url(r'^item/(?P<id>\w+)/', views.index_items, name = 'index items'),
url(r'^userstats/(?P<id>\w+)/', views.user_stats, name='user profile'),
url(r'^create/$', views.create, name='create'),
url(r'^create/(?P<id>\w+)/', views.create_specific_item, name = 'create specific item'),
url(r'^mylist/$', views.my_list, name='mylist'),
url(r'^mylist/stats/$', views.my_list_stats, name='mylist stats'),
url(r'^mylist/edit/(?P<id>\w+)/', views.edit_bucket_list_item, name = 'edit my list item'),
url(r'^mylist/view/(?P<id>\w+)/', views.view_my_list_item, name = 'view my list item'),
url(r'^mylist/uncross/(?P<id>\w+)/', views.uncross_my_list_item, name = 'uncross my list item'),
url(r'^mylist/crossoff/(?P<id>\w+)/', views.cross_off_my_list_item, name = 'cross off'),
url(r'^mylist/deleteitem/(?P<id>\w+)/', views.delete_my_list_item, name = 'delete list item'),
url(r'^mylist/recommendation/$', views.recommendation, name = 'recommendation'),
url(r'^profile/edit/$', views.edit_profile, name = 'edit profile'),
)
settings.py
"""
Django settings for Bucket project.
For more information on this file, see
https://docs.djangoproject.com/en/1.6/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.6/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
DEBUG = True
TEMPLATE_DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'BucketList',
'south',
)
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'templates')]
ROOT_URLCONF = 'Bucket.urls'
WSGI_APPLICATION = 'Bucket.wsgi.application'
# Database
# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.6/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.6/howto/static-files/
STATIC_URL = '/static/'
LOGIN_URL = '/accounts/login/'
views.py
from django.shortcuts import render
from django.http import HttpResponse
from BucketList.models import BucketListItem, UserProfile, Comment
from django.contrib import auth
from forms import BucketListItemForm, UserProfileForm, UserProfileEditForm, BucketListItemEditForm, CustomItemEditForm, CommentForm
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from django.contrib.auth.models import User
from django.db.models import Sum
from django.contrib.auth.forms import UserCreationForm
from django.utils import timezone
from django.contrib.auth.decorators import login_required
def index(request):
#The main Bucket List Page View, sorted by pubdate so the most recent are at the top
all_list_items = BucketListItem.objects.all().order_by('-pub_date')
context = {'all_list_items': all_list_items}
return render(request, 'BucketList/index.html', context)
#login_required
def index_items(request, id):
#When a user clicks on a Bucket List Item on the index page it will take them here with a brief overview of that items information
item = BucketListItem.objects.get(pk = id)
current_user = UserProfile.objects.get(pk = request.user.id)
comments = Comment.objects.filter(item = item)
if request.POST:
form = CommentForm(request.POST)
if form.is_valid():
body = form.cleaned_data['body']
my_model = form.save(commit = False)
my_model.created = timezone.now()
my_model.author = current_user.user
my_model.item = item
my_model.body = body
my_model.save()
form = CommentForm()
else:
form = CommentForm()
context = {'item': item,
'id': id,
'comments': comments,
'form': form,
}
context.update(csrf(request))
return render(request, 'BucketList/index_items.html', context)
#login_required
def user_stats(request, id):
#A public stats/profile page that displays their basic profile information as well as their bucket list
item = User.objects.all().filter(username = id)
item_profile = item[0].userprofile
list_of_all = BucketListItem.objects.all().filter(pub_by = item)
context = {'id': id,
'item': item[0],
'list_of_all': list_of_all,
'item_profile': item_profile,
}
return render(request, 'BucketList/user_stats.html', context)
#login_required
def index_stats(request):
#This page compiles interesting statistics about all of the Bucket List Items on the main index page and displays that information
list_of_all = BucketListItem.objects.all().count()
total_cost = BucketListItem.objects.all().aggregate(Sum('cost'))
total_time = BucketListItem.objects.all().aggregate(Sum('time'))
total_crossed_off = BucketListItem.objects.all().aggregate(Sum('crossed_off'))
number_of_users = User.objects.all().count()
cost_per_user = total_cost['cost__sum']/number_of_users
time_per_user = total_time['time__sum']/number_of_users
items_per_user = list_of_all/number_of_users
crossed_off_per_user = total_crossed_off['crossed_off__sum']/number_of_users
context = {'list_of_all': list_of_all,
'total_cost': total_cost['cost__sum'],
'total_time': total_time['time__sum'],
'total_crossed_off': total_crossed_off['crossed_off__sum'],
'crossed_off_per_user': crossed_off_per_user,
'number_of_users': number_of_users,
'cost_per_user': cost_per_user,
'time_per_user': time_per_user,
'items_per_user': items_per_user,
}
return render(request, 'BucketList/index_stats.html', context)
#login_required
def my_list(request):
#The current users personal Bucket List view with links to create more list items or learn statistics about their list
personal_list = BucketListItem.objects.all().filter(pub_by = request.user.id)
context = {'personal_list': personal_list,
'user': request.user.username
}
return render(request, 'BucketList/mylist.html', context)
#login_required
def my_list_stats(request):
#General statistics about the current users Bucket List
personal_list = BucketListItem.objects.all().filter(pub_by = request.user.id)
total_cost = BucketListItem.objects.all().filter(pub_by = request.user.id).aggregate(Sum('cost'))
total_time = BucketListItem.objects.all().filter(pub_by = request.user.id).aggregate(Sum('time'))
total_crossed_off = BucketListItem.objects.all().filter(pub_by = request.user.id).aggregate(Sum('crossed_off'))
cost_per_list_item = total_cost['cost__sum']/personal_list.count()
time_per_list_item = total_time['time__sum']/personal_list.count()
context = {'personal_list': personal_list,
'user': request.user.username,
'total_cost': total_cost['cost__sum'],
'total_time': total_time['time__sum'],
'total_crossed_off': total_crossed_off['crossed_off__sum'],
'cost_per_list_item': cost_per_list_item,
'time_per_list_item': time_per_list_item,
}
return render(request, 'BucketList/my_list_stats.html', context)
#login_required
def view_my_list_item(request, id):
#View of a current users Bucket List Item with options to cross off or edit the Bucket List Item
logged_in = request.user.id
item = BucketListItem.objects.filter(pk = id)
context = {'logged_in': logged_in,
'item': item[0],
}
return render(request, 'BucketList/view_my_list_item.html', context)
#login_required
def cross_off_my_list_item(request, id):
#The view that crosses off the Bucket List Item
item = BucketListItem.objects.get(pk = id)
item.crossed_off = True
item.pub_date = timezone.now()
item.save()
context = {'item': item,
'User': User,
}
return render(request, 'BucketList/crossed_off.html', context)
#login_required
def uncross_my_list_item(request, id):
#The view that uncrosses off the Bucket List Item
item = BucketListItem.objects.get(pk = id)
item.crossed_off = False
item.pub_date = timezone.now()
item.save()
context = {'item': item,
'User': User,
}
return render(request, 'BucketList/uncross.html', context)
#login_required
def delete_my_list_item(request, id):
#The view that uncrosses off the Bucket List Item
item = BucketListItem.objects.get(pk = id)
title = item.text
item.delete()
context = {'title': title,
'User': User,
}
return render(request, 'BucketList/delete.html', context)
#login_required
def create(request):
#Creates a Bucket List Item, the user only fills out the Name and Type of the item while the rest of the fields are auto-filled: publication date, published by, crossed off, time, hours, and cost
if request.POST:
form = BucketListItemForm(request.POST)
if form.is_valid():
user = User.objects.get(id=request.user.id)
my_model = form.save(commit = False)
new_cost = form.cleaned_data['cost']
new_time = form.cleaned_data['time']
new_hours = form.cleaned_data['hours']
my_model.pub_by = user
my_model.crossed_off = False
my_model.time = new_time
my_model.hours = new_hours
my_model.cost = new_cost
my_model.save()
return HttpResponseRedirect('/bucketlist/mylist/')
else:
form = BucketListItemForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render(request, 'BucketList/create_item.html', args)
#login_required
def edit_bucket_list_item(request, id):
#This view lets the user edit their Bucket List Item and directs them to other forms necessary to make the changes needed
item = BucketListItem.objects.get(pk = id)
if request.method == "POST":
form = BucketListItemEditForm(request.POST)
if form.is_valid():
text = form.cleaned_data['text']
goal_type = form.cleaned_data['goal_type']
cost = form.cleaned_data['cost']
time = form.cleaned_data['time']
hours = form.cleaned_data['hours']
item.text = text
item.cost = cost
item.time = time
item.hours = hours
item.goal_type = goal_type
item.pub_date = timezone.now()
item.save()
return HttpResponseRedirect('/bucketlist/mylist/')
else:
form = BucketListItemEditForm({'text': item.text, 'goal_type': item.goal_type, 'cost': item.cost, 'time': item.time, 'hours': item.hours})
context = {'form': form,
'id': item.id,
}
context.update(csrf(request))
return render(request, 'BucketList/edit_bucket_list_item.html', context)
#login_required
def edit_profile(request):
#A view that allows the user to edit their current profile information
current_user = UserProfile.objects.get(pk = request.user.id)
if request.method == "POST":
form = UserProfileEditForm(request.POST)
if form.is_valid():
new_age = form.cleaned_data['new_age']
new_life_expectancy = form.cleaned_data['new_life_expectancy']
new_yearly_earnings = form.cleaned_data['new_yearly_earnings']
new_hourly_wage = form.cleaned_data['new_hourly_wage']
current_user.yearly_earnings = new_yearly_earnings
current_user.hourly_wage = new_hourly_wage
current_user.life_expectancy = new_life_expectancy
current_user.age = new_age
current_user.save()
return HttpResponseRedirect('/bucketlist/mylist/')
else:
form = UserProfileEditForm({'new_age': current_user.age, 'new_life_expectancy': current_user.life_expectancy, 'new_yearly_earnings': current_user.yearly_earnings, 'new_hourly_wage': current_user.hourly_wage})
context = {'form': form,
}
context.update(csrf(request))
return render(request, 'BucketList/edit_user_profile.html', form)
Looking at your views it seems you are calling csrf() on the request, and then sending the response back with render. The whole point of render is that it automatically enforces all context processors, so you don't have to manually call csrf().
Even though it usually shouldn't matter, in my experience I have noticed that a duplicate call to csrf can sometimes cause weird and unexpected behavior after a few requests.
As we discussed in the comments, after applying this change (among a few others) the problem stopped happening. My prime suspect is the csrf() call but it can easily be that you had a corrupted django installation (next time, use a virtualenv) or some other local issue that had nothing to do with django.

Categories

Resources