How to let PIL's Image.open find files from static? - django

I want to access a file in static from a module called "generate.py" inside my app. However I don't really have any idea how to do it.
I believe I've properly "installed" the app because i can access the .html file in the App
Things I've tried in generate.py
1 -
from django.conf.urls.static import static
Image.Open(static('resources/App/template/photothatiwanttoopen.jpg'))
Error I get from code above: 'list' object has no attribute 'read'
2 -
from django.conf import settings
Image.Open(settings.STATIC_URL+'resources/App/template/photothatiwanttoopen.jpg')
Error I get from code above: [Errno 2] No such file or directory: '/static/resources/App/template/photothatiwanttoopen.jpg'
Here's my folder structure view
- Project
- App
- templates
- App
- app.html
- apps.py
- generate.py <<< Script
- models.py
- urls.py
- views.py
- Project
- settings.py and stuffs
- static
- resources
- App
- template
- photothatiwanttoopen.jpg
- manage.py and stuffs
Here's last few lines of my settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Let me know if you need any more information.

STATIC_URL has no concept of the actual location on the filesystem.
That's where STATIC_ROOT comes into play.
Your optimal choice is likely going to be:
Image.Open(os.path.join(STATIC_ROOT, 'resources/App/template/photothatiwanttoopen.jpg'))
That is assuming of course you've already collected the staticfiles (manage.py collectstatic) and you have imported STATIC_ROOT from django settings.

Related

Serving Static files on AWS Django application

I know that this isn't the first time the question has been asked, so I'm apologizing up front. I've been working on this for a few days and still have no clue how to proceed.
I followed this tutorial to the tee: https://aws.amazon.com/getting-started/hands-on/deploy-python-application/
The website is up and running, but of course the static files won't load.
Here's where I'm at. In settings.py, I've set my STATIC_ROOT and STATIC_URL to the following:
STATIC_ROOT = os.path.join(BASE_DIR, 'mysite', 'static')
STATIC_URL = '/static/'
I ran collectstatic and gathered all my static files into the mysite app directory. It looks like this:
-mysite
- mysite (app)
- static
- base
- base.css
- settings.py
- urls.py
- wsgi.py
Unfortunately, the static files still fail to load on the website.
Here are my questions:
Suppose I wanted to view the base.css text file on the web. Would I go to www.mysite.com/static/base/base.css? If no, what would the URL be? If yes, why is it not appearing given the current set up?
Per the AWS tutorial, I ran edited the httpd-app.conf file to include the following
Alias /mysite/static /opt/bitnami/apps/django/lib/python3.7/site-packages/Django-2.2.9-py3.7.egg/django/contrib/admin/static
What was the purpose of the edit? How does it impact how the static files are served on the site?
Any help you guys can offer on loading these static files will be a lifesaver.
Your urls.py file needs to be configured to serve your STATIC_URL
urls.py
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
More on serving static files with Django

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)

Prod server serving files only when debug turned on- Django

I am trying to serve dynamically created files on my Django server.
The code works fine and serves the image file from media folder on my local server.
It also works and serves the image file in Production server but only when I set debug to True in Prod server.
But when I set debug to False in Prod Server, I get a file not found error (in console):
GET http://thesitename/media/imgs/img.png 404 (Not Found)
The server serves the files from the /static folder, but does not serve the files from /media folder.
my settings.py looks like this:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "frontend/media/")
urls.py looks like this:
app_name = 'frontend'
urlpatterns = [ ###urls###
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Views.py looks like this:
def template_page(request, loation, par, date):
### generating image using pil here ###
pil_image.save("frontend/media/imgs/img.png”)
path_to_image_passing_to_template = “/media/imgs/img.png”
params = {
'path_to_image_passing_to_template' : path_to_image_passing_to_template
}
return render(request, 'frontend/template_page.html', params)
html looks like this:
<img src="{{path_to_image_passing_to_template}}" />
and file structure is like this:
/backend
urls.py
views.py
/frontend
/static
/media
/imgs
/templates
/frontend
urls.py
views.py
/thesite
settings.py
urls.py
wsgi.py
/static
I don't understand why it should work with debugging turned on in prod server and not otherwise!!!
I have looked at several questions but did not find any query close to this kind of issue. I took some help while writing working out the dynamic media files code from this answer earlier but am stuck right now.
Confirm that you have 'os.environ' module loaded...try executing the
code below on the production server.
import os
print(os.environ.get('MEDIA_ROOT'))
Make sure it shows the expected path.
then ensure that your 'urls.py' and 'Views.py' have 'import os' line appearing at the top of the file. Good Luck!

Django folder structure

What would be a good structure (best practise) for the folders in a Django application (1.7)?
I'm not sure where to put the static data and file Uploads.
In all my projects it turns out different, but currently I have something like this (I left out a few obvious folders/files):
project/
bin/
include/
...
src/
manage.py
main/
- settings.py
- urls.py
signup/
static/
static_/
+ css
+ img
+ js
static/
templates/
- index.html
- base.html
- ...
uploads/
And also, I'd prefer to see url's like for example site.com/css/file.css instead of site.com/static/css/file.css , but somehow thats more complicated then it seems. How can that be accomplished?
I use the the following in setting.py (using Django v1.6.8 at the moment)
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
#TEMPLATE_DIRS = (os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "static", "templates"),)
TEMPLATE_DIRS = (
os.path.join(BASE_DIR, 'templates'),)
This gives me a folder layout
project/
manage.py
project_app/
- settings.py
- urls.py
someother_app/
- admin.py
- models.py
- views.py
static/
css/
javascript/
templates
admin/
someother_app/
- base.html
- index.html
media/
I'm not sure what you mean when you say site.com/css/file.css. Something like <link rel="stylesheet" href="{{ STATIC_URL }}css/jquery.asmselect.css"> in the <head> of base.html uses the Django Framework to present your .css files. Why not use what is there? Saves time and effort.
Tommy.
Here is a recommendation for the Django project layout from the book Two Scoops of Django:
repo_root/
.gitignore
Makefile
docs/
README.rst
requirements.txt
django_project_root/
manage.py
media/
django_app_root/
static/
templates/
config/
__init__.py
settings/
urls.py
wsgi.py
and is considered a three level project layout where:
Top Level (repo_root): high-level files required for deployment
Second Level (django_project_root): actual django project
Third Level (config): the django project configuration files.
Regarding file Uploads I would upload them from the browser directly to Amazons S3 file storage (or similar service). Otherwise you're hogging bandwidth and CPU time. Or if you must then in the media folder ^ and for security reasons please validate the file types uploaded.

Django Static Files CSS

How can I view my static css files? I've set my STATIC_ROOT, and am using python manage.py runserver.
In my development environment, according the docs, I only need to place my static files (in this case, /static/css/typography.css) in my STATIC_ROOT, and python manage.py runserver will automatic create the views necessary to access it if I have DEBUG = True.
STATIC_ROOT = os.path.join(os.path.abspath(os.path.dirname(__file__)), "static")
I've also tried manually adding the views in URLConf, which won't display the css file either:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# ... the rest of your URLconf goes here ...
urlpatterns += staticfiles_urlpatterns()
In my template, the {{ STATIC_URL }} gets to the correct address (/static/css/typography.css), but it will not serve the file when I try to access it:
<link href="{{ STATIC_URL }}css/typography.css" rel="stylesheet" type="text/css">
Notes: The other Django related static files questions on StackOverflow are over two years old. Django version 1.3b1 differentiates STATIC (static files, such as css and images) and MEDIA (user-uploaded file).
Besides. all the tries mentioned above, you must also make sure that your template is receiving the RequestContext when called from the view.
http://lincolnloop.com/blog/2008/may/10/getting-requestcontext-your-templates/
This link gives various ways of doing the same and you could choose any one. :) Also, the TEMPLATE_CONTEXT_PROCESSORS must be added to settings.py for this to take effect.
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"myapp.processor.foos",
)
Note: STATIC_ROOT is the place where all your static files are stored by Django after collecting them from STATICFILES_DIRS.
Runserver will pick them up from the path mentioned in STATIC_ROOT, so STATIC_URL should point to the same location as STATIC_ROOT.
Answered here: Django staticfiles app help
I was putting my files in STATIC_ROOT, so adding this works:
STATICFILES_DIRS = (STATIC_ROOT,)
In development:
#settings.py have this by default
STATIC_URL = '/static/'
This means when you want to use static files, django will look for them in folder 'static' in your app directory. So you need to create folder 'static' in every your app and put inside your static files.
In production:
1. Make place to hold static files from all app's
STATIC_ROOT = "/var/www/example.com/static/"
2. Run python manage.py collectstatic to collect static files from all app's in STATIC_ROOT folder.
3. In settings.py change DEBUG=False and ALLOWED_HOSTS = ['yourhostadress'].
4. Point your webserver to STATIC_ROOT folder (eg. for Apache2.4):
Alias /static/ /path/to/mysite.com/static/
<Directory /path/to/mysite.com/static>
Require all granted
</Directory>
After this setup, your django project should be able to run (using mod_wsgi) and use static files on Apache web server.