Django model cannot find a static file - django

in my models.py I have (myfile.txt is 3gb)
with open('/static/myfile.txt', 'rb') as f:
do something..
but it complains
No such file or directory: '/static/myfile.txt'
this is my settings.py
STATIC_ROOT = 'absolute_dir_to_project/app_name/static/'
STATIC_URL = '/static/'
Did I miss any step?

you should prepend the absolute path with SETTINGS's STATIC_URL so that it looks for myfile.txt inside Django:
from django.conf import settings # dont forget to import this guy
with open(settings.STATIC_URL + 'myfile.txt', 'rb') as f:
do something..

The open function is trying to open a file from disk with the path /static/myfile.txt, rather than requesting a file through your Django web app. It doesn't sound like you need to have this file in your static files folder, especially if it's huge and isn't intended for public consumption

Related

Accessing .csv data from views file

I have a small Django app, and I'm trying to access data from a CSV file (static/blog/dat.csv, the static folder is at the same level as the templates folder and views.py; and everything is inside my blog app) so I can use it to plot a graph on the browser using Chart.js. Aside from not being able to do that, the app is working fine.
I know I'm gonna need to pass some sort of context to the view function, but I don't know how I'd do that. Also, I have a couple of similar csv files, and using them as static files in my app seems simpler and easier than to add everything to a database to access them that way.
# views.py
from django.shortcuts import render
from django.contrib.staticfiles.storage import staticfiles_storage
import csv
def rtest(request):
url = staticfiles_storage.url('blog/dat.csv')
with open(url, 'r') as csv_file:
csv_reader = csv.reader(csv_file)
for line in csv_reader:
context += line
return render(request, 'blog/r.html', context)
# urls.py
urlpatterns = [
# ...
path('r-test/', views.rtest, name='blog-r-test'),
]
Here is the error I'm getting:
FileNotFoundError at /r-test/
[Errno 2] No such file or directory: '/static/blog/dat.csv'
I'm sure this is not the only error.
I know that the way I'm using the context variable is wrong, but that's just to kind of show what I'm trying to do. If I could just print one cell from the csv, I would view this as a win. Please help, thank you!
------Edit1-------
After using staticfiles_storage.path() instead of staticfiles_storage.url()
ImproperlyConfigured at /r-test/
You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
------Edit2------
I'm now able to find my csv file:
STATIC_URL = '/static/'
STATIC_ROOT = 'C:/Users/riccl/Documents/richie/Python/nuclear/main/book/static/book'
But my context variable still doesn't make any sense.
You need to use staticfiles_storage.path() to read the file. staticfiles_storage.url() will return the URL that a user will use to load the static file on your site
STATIC_ROOT is where all static files will be stored after you run collectstatic, most of the time this is set to <root of the project>/static/. This is also where staticfiles_storage.path() will look for static files.
You will also need to set STATICFILES_DIRS so that your file(s) can be found by collectstatic. I usually have a folder located at <root of the project>/<project name>/static/ which I add to STATICFILES_DIRS

FileNotFoundError for the media folder after deploying Django app on Apache

I have a Django app that I just added to the already deployed Django web on Apache.
Because it is ran by Apache, path of the media folder seems to be different.
My app lets the user upload an excel file which then changes numbers and save as csv file.
(only showed relevant folders/code snippets)
Current directory
converts\
_init_.py
apps.py
forms.py
models.py
converter.py
urls.py
views.py
main\
settings.py
urls.py
wsgi.py
meida\
excels\
example.xlsx
csvs\
example.csv
static\
manage.py
settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
main\urls.py
urlpatterns = [
path('', RedirectView.as_view(url='/converts/')),
path('converts/', include('converts.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The part that causes the problem is the following in converts/converter.py:
def convertExcel(name):
path = 'media/excels/'
key = path + name
wb = load_workbook(key)
Originally in development, a function in view calls convertExcel(example.xlsx) and the workbook, via media/excels/example.xlsx, finds the correct file to work with the loaded workbook. But in production server, it gives
FileNotFoundError: [Errno 2] No such file or directory: 'media/excels/example.xlsx'
My Question is:
Do I have to back track from where apache2.conf is to find the path? Or is there a way to set path to my django project so i can just set path in my convertExcel() as 'media/excels'? Or is there any other way I can call the uploaded workbook?
Any kind of help/comment would be appreciated.
Please comment if additional information is needed.
My guess is that you should use MEDIA_ROOT variable because it points to the uploaded files. So you would have
def convertExcel(name):
from django.conf import settings
path = os.path.join(settings.MEDIA_ROOT, 'excels')
key = os.path.join(path, name)
wb = load_workbook(key)

File not found on pythonanywhere.com

On pythonanywhere.com I have a django app. This is views.py:
def literature(request):
module_dir = os.path.dirname(__file__)
file_path = os.path.join(module_dir, 'literature.csv')
with open(file_path, 'r') as f:
...
File literature.csv is located at the same directory as views.py. But every time when I try to load the page I get FileNotFoundError. The same construction works normally on local server. Where is the bug?
This os.path.dirname(__file__) is giving you a relative path. On your local server, it just happens that it corresponds to the correct path. On PythonAnywhere, use the full path for module_dir. Like this: os.path.abspath(os.path.dirname(__file__))

Reading a static file

I have a Django project called myproject, which has an app called myapp. I want to read a text file and load its contents into a list. I'm a little confused about static files and relative directories in Django, and my initial attempt is not working. So far, I have the following code...
In /myproject/settings.py:
STATIC_URL = '/static/'
In /myapp/static/myapp, there is a file called myfile.txt.
In /myapp/views.py:
with open('myapp/myfile.txt') as f:
lines = f.readlines()
When running the server, I get the error: No such file or directory: 'myapp/myfile.txt'
What am I doing wrong?
in your settings:
import os
gettext = lambda s: s
PROJECT_PATH = os.path.normpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
MEDIA_ROOT = os.path.join(PROJECT_PATH, "media")
MEDIA_URL = "/media/"
create a folder media under your app folder.
then put the file you want to read in that folder.
and try this in your views.py:
from django.conf import settings
with open(settings.MEDIA_ROOT + '\\yourfile.text', 'rb') as f:
lines = f.readlines()

How to get the link of the file in a FileField?

how can I get the link of a FileField? I tried the url field, but it gives the file path:
In [7]: myobject.myfilefield.path
Out[7]: u'/home/xxxx/media/files/reference/1342188147.zip'
In [8]: myobject.myfilefield.url
Out[8]: u'/home/xxxx/media/files/reference/1342188147.zip'
I was expecting to get http://<mydomain>/media/files/reference/1342188147.zip
How can I get that? Do I have to build the string manually?
EDIT
My MEDIA_URL was not set, but I still can't get it to work:
settings.py
MEDIA_ROOT = '/home/xxx/media/'
MEDIA_URL = 'http://xxx.com/media/'
models.py
class Archive(models.Model):
#...
file = models.FileField(upload_to="files")
in shell
a = Archive()
a.file = "/some/path/to/file.txt"
a.save()
Then I get for a.path:
"/some/path/to/file.txt"
and for a.url:
"http://xxx.com/media/some/path/to/file.txt"
When done programmatically, a.file = "/some/path/to/file.txt", the file is not uploaded to MEDIA_ROOT. How can I upload a file in the directory defined by upload_to, i.e. in my case /home/xxx/media/file.txt?
The output is based on your settings file, have a look here for an understanding on serving staticfiles in development and/or production:
Confusion in Django admin, static and media files
I'm guessing you have the field defined as:
picture = models.ImageField(upload_to="/home/xxx/media/files/reference")
in other words is it possible you have defined an absolute path for the upload_path property of the field ?
Try something like
from django.conf import settings
picture = models.ImageField(upload_to=settings.MEDIA_ROOT + "files/reference")