I am using Python PIL library in Django Rest Framework for building qr code and saving it to static directory.
def generate_qr(self, name):
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_M,
box_size=15,
border=5
)
qr.add_data(name)
qr.make(fit=True)
img = qr.make_image(fill='black', back_color='white')
img.save(settings.STATIC_ROOT+"/asset-tags/name.png")
return(name+ '.png')
settings.py for media and static urls:
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_URL = "/mediafiles/"
MEDIA_ROOT = os.path.join(BASE_DIR, "mediafiles")
But while saving it throws an error saying /usr/app/static/name.png : no file or directory.
I am creating new file so how can it find the image in given folder.
Any Help will be appreciated. Thanks.
The qrcode package or Pillow package won't create a directory if it doesn't exist. So, as per your settings, the STATIC_ROOT is located at /staticfiles and make sure that the directory named staticfiles (and it's sub-directories) exists before runs your script.
In other words, the statement img.save(settings.STATIC_ROOT+"/asset-tags/name.png") supposed to be save the QR code image under this path /staticfiles/asset-tags/name.png and make sure the directory /staticfiles/asset-tags/ exists in your project path.
NOTE: Use settings.MEDIA_ROOT instead of settings.STATIC_ROOT would be more appropriate.
Related
Before marking as duplicate, note that I've checked all the similar questions that have been asked and it has not fixed my problem. I've deployed my Django App on Heroku in in one template where I reference a min.js file, it throws this error in question.
My basic directory structure is this:
myapp
mysite
dictionary
static
jquery.twbsPaginationAlt.min.js
staticfiles
settings.py:
STATIC_URL = '/static/'
# STATIC_ROOT = [os.path.join(BASE_DIR, 'staticfiles'), os.path.join(BASE_DIR, 'static/fonts')]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
if DEBUG:
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'mysite/static'), os.path.join(BASE_DIR, 'static/')]
import django_heroku
# handles staticfiles, database url, and secret key, can be overwritten as needed
django_heroku.settings(locals(), secret_key=False, logging=False)
So originally if STATICFILES_DIRS had any value, I would get an error of FileNotFoundError: [Errno 2] No such file or directory: '/tmp/build_6f3eb879/mysite/static' when running collectstatic on heroku. However, if it is not set, than the fonts I have in my dev environment do not load in properly (I also have fonts inside the base level static folder).
This is how I reference the js file in my problem template, it works fine on dev:
<script src='{% static 'jquery.twbsPaginationAlt.min.js' %}'></script>
For convenience, here is what django-heroku does in terms of staticfiles:
logger.info('Applying Heroku Staticfiles configuration to Django settings.')
config['STATIC_ROOT'] = os.path.join(config['BASE_DIR'], 'staticfiles')
config['STATIC_URL'] = '/static/'
# Ensure STATIC_ROOT exists.
os.makedirs(config['STATIC_ROOT'], exist_ok=True)
# Insert Whitenoise Middleware.
try:
config['MIDDLEWARE_CLASSES'] = tuple(['whitenoise.middleware.WhiteNoiseMiddleware'] + list(config['MIDDLEWARE_CLASSES']))
except KeyError:
config['MIDDLEWARE'] = tuple(['whitenoise.middleware.WhiteNoiseMiddleware'] + list(config['MIDDLEWARE']))
# Enable GZip.
config['STATICFILES_STORAGE'] = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
(from https://github.com/heroku/django-heroku/blob/master/django_heroku/core.py)
EDIT:
In order to fix this I had to stop using django heroku, change my STATICFILES_STORAGE variable to whitenoise.storage.CompressedStaticFilesStorage , and reorganize where I kept some of my static files by checking the logs to see what path the GET requests were going to. It seems whitenoise is pretty imperfect based off the other stackoverflow posts I've seen, it consistently misses 'static/' files in the root directory. Additionally since Django relies a lot on the 'static' keyword in templates, and this is not available in .css files, the only way to resolve getting static files into a css file (for fonts for example), is trial and error of testing different paths.
This line looks very odd to me and may be the source of the problem:
if DEBUG:
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'mysite/static'), os.path.join(BASE_DIR, 'static/')]
Why are you only defining your STATICFILES_DIRS in debug mode? You'll need those defined in production too.
in my Django app I´m trying to open and show pdf files that wasn't loaded to a model, but can´t find the appropriate way.
I have a group of PDF invoices that I manually copied to media/my_folder (I use Dropbox as media host to be able to do that).
Then I want to show each invoice when requested.
File object option
After investigating several posts, I think the way to do it is creating a file object dynamically.
invoice_path = "my_folder/" + invoice_number + ".pdf"
f = open(invoice_path, 'w')
myfile = File(f)
Then I understand the in the template I could be able to access the file as it was loaded to the model.
<p>Ver factura AFIP</p>7
I get a FileNotFoundError, I guess I´m not setting the path to media files correctly.
Exception Type: FileNotFoundError at /catalog/perfilfactura/FA B
0003-00000220 Exception Value: [Errno 2] No such file or
directory: 'media/Facturas_Electronicas/FA-B-0003-00000220.pdf'
This happens when trying to open the file. The path I set it's supposed to be relative to MEDIA_ROOT, just add the subfolder "my_folder" and then the pdf file name.
Path in template option
I also tried to set the path directly in the template as in:
<p><a href="media/{{ archivo_factura }}.pdf" download>Ver factura AFIP</a></p>
<p><a href="{{ MEDIA_URL }}Facturas_Electronicas/{{ archivo_factura }}.pdf" download>Ver factura AFIP</a></p>
In both cases I get a downloaded ampty PDFs.
My settings:
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
And my Dropbox settings:
DEFAULT_FILE_STORAGE = 'storages.backends.dropbox.DropBoxStorage'
DROPBOX_OAUTH2_TOKEN = 'my_token'
DROPBOX_ROOT_PATH = '/Kinemed APP/'
Thanks!
There doesn't seem to be any reason to either open the file or create a File object. If your file is inside the media directory, all you need to do to create a URL for it is to join the media root:
invoice_path = os.path.join(settings.MEDIA_ROOT, "my_folder/" + invoice_number + ".pdf")
and now pass invoice_path directly to the template and access it there.
I was tried n I can't set-up as per official documents...
I am attaching IMG here, pls give me suggestions, Where is the problem.enter image description here
Or, give me simple steps for it with dictionary tree structure.
Thank you.
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root', 'static')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
# '/var/www/static/',
)
STATIC_ROOT = 'os.path.join(BASE_DIR, 'static_root', 'static') can't work.
Try this :
# define your base directory
# It will be `absolute/path/to/demo3`
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
STATIC_URL = '/static/'
# define where your static files will be collected
# It will be `absolute/path/to/demo3/static`
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# keep it empty for the moment
STATICFILES_DIRS = (
)
You have to understand STATICFILES_DIRS role :
Your project will probably also have static assets that aren’t tied to
a particular app. In addition to using a static/ directory inside your
apps, you can define a list of directories (STATICFILES_DIRS) in your
settings file where Django will also look for static files.
I recommend you to read carefully Django docs : Managing static files
STATIC_ROOT should be without quotes:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Also, the STATIC_ROOT folder shouldn't be named the same as the STATICFILES_DIR folder, so you should name it something like staticfiles instead:
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles/')
STATIC_ROOT = 'os.path.join(BASE_DIR, 'static')' is a string which is wrong.
it should be STATIC_ROOT = os.path.join(BASE_DIR, 'static')
The error is clear in stating the STATIC_ROOT is not a filesystem path. Django requires that STATIC_ROOT be an absolute path to a folder location on the machine. This error likely means that your resulting STATIC_ROOT is a partial or relative path. What is the value of BASE_DIR? After the line that sets STATIC_ROOT and a print(STATIC_ROOT) to see what value it is.
Try setting BASE_DIR as follows:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Other Errors
On the line
STATIC_ROOT = 'os.path.join(BASE_DIR, 'static')'
You have the value surrounded by single quotes. os.path.join() is a function call. Remove the quotes and change the line like this:
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
Also, STATIC_ROOT cannot be included in the list of files in STATICFILES_DIRS. Consider setting the STATIC_ROOT folder to:
STATIC_ROOT = os.path.join(BASE_DIR, 'static_root')
when creating the project with latest version of python and django in settings.py file by default from pathlib import Path Statement is there.So in that case no need to use os.path.
from pathlib import Path # Import First
STATIC_ROOT = Path.joinpath(BASE_DIR, 'static_collected')
I added one line code and it worked for me, I hope it doesn't pain in the future :)
import os
Remember to create a static folder in your root directory and also create the static folder in your project folder. Then your file structure would be:
demo3
/demo3/staticfiles # collection folder for all static files
/static # root static folder
/userForms/static # your app static files
# OR
demo3
/demo3
/static_files # collection folder for all static files
/static # root static folder
/userForms/static # your app static files
Add this to your settings.py
STATIC_ROOT = os.path.join(BASE_DIR, 'demo3', 'staticfiles')
OR depending on where you want the collection folder
STATIC_ROOT = os.path.join(BASE_DIR, 'static_files')
Run python manage.py collectstatic
Then it would bundle all static files in project staticfiles OR root static_files folder, depending on where you want them.
I want to be able to define my settings for static/media files using python to get the paths so I don't need different settings on my dev machine and my server.
So I have these settings;
import os
from unipath import Path
### PATH CONFIGURATION
# Absolute filesystem path to the top-level project folder
SITE_ROOT = Path(__file__).ancestor(3)
### MEDIA CONFIGURATION
MEDIA_ROOT = SITE_ROOT.child('media')
MEDIA_URL = '/media/'
### END MEDIA CONFIGURATION
### STATIC CONFIGURATION
STATIC_ROOT = SITE_ROOT.child('static')
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = os.path.join(SITE_ROOT, 'static'),
My problem is that locally it won't load the static files and the terminal says that STATICFILES_DIRS should not contain the STATICFILES_ROOT.
Is it possible to get Python to load the paths like this or am I wasting my time?
There's nothing wrong with your code per se, it's just that the point of the staticfiles app is to copy the files from the directories specified in STATICFILES_DIRS into the directory specified in STATIC_ROOT, so it doesn't make much sense to include the STATIC_ROOT directory in the STATICFILES_DIRS setting.
Unless you're actually using the staticfiles app with ./manage.py collectstatic, you may as well just leave the STATICFILES_DIRS setting empty, i.e. just change...
STATICFILES_DIRS = os.path.join(SITE_ROOT, 'static'),
...to...
STATICFILES_DIRS = ()
Do like this:
import os
settings_dir = os.path.dirname(__file__)
PROJECT_ROOT = os.path.abspath(os.path.dirname(settings_dir))
MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media/')
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static/')
STATICFILES_DIRS = (
os.path.join(PROJECT_ROOT, 'static/'),
)
That should work. Hope it helps!
+1 for both other answers. If you get tired of typing os.path.bla a lot here's a shortcut you can position at the top of your settings file (or import from anywhere else)
def rel(*x):
return os.path.join(os.path.abspath(os.path.dirname(__file__)), *x)
STATICFILES_DIRS = (
rel('static'),
)
So i've been googling this issue for the past hour and can't come up with a solution. Basically this is it: in my model.py i have a class that has this
class Case(models.Model):
zoomOutImage = models.ImageField('Label', upload_to="zoomOutImage")
and in my settings.py i have my media URL/ROOT set up like this
MEDIA_ROOT = os.path.join(os.path.abspath(''),'app/static/ds/')
MEDIA_URL = '/static/ds/'
which from the webserver should serve out like this:
http://127.0.0.1:8000/static/ds/zoomOutImage/actinic_granuloma_3.jpg
I've installed PIL (inside virtualENV) and there are no errors in uploading, the only issue is when i try uploading the file via the admin panel nothing happens. No errors nothing. The file just simply doesn't get uploaded to the zoomOutImage folder by the development server. Can anyone point me towards why?
I guess your file is in a subdir of your root, subdir named 'zoomOutImage'. Or even a file called like that in the root. I remember putting a function call in the upload to string. That function creates a path and filename, using os.join and the filename from the instance. Doing this by head, no example code available right now. But must be able to google this.
Look here https://stackoverflow.com/questions/1190697/django-filefield-with-upload-to-determined-at-runtime
And by the way, I totally disagree with your answer, you should NEVER use absolute paths in your settings! See this answer use css in django 1.4 development for how to use the correct settings and refer to your Project PATH
EDIT (after reading your own answer)
Guess you are missing this first step:
this is the path to your settings.py file:
SETTINGS_DIR = os.path.dirname(os.path.realpath(__file__))
and than this is the path to your project dir: (I Am using buildout, so call it buildout, but it's the root of your project):
BUILDOUT_DIR = os.path.abspath(os.path.join(SETTINGS_DIR, '..'))
and from there on you can define everything you want:
STATIC_ROOT = os.path.join(BUILDOUT_DIR, 'var', 'static')
STATIC_URL = '/static_media/'
MEDIA_ROOT = os.path.join(BUILDOUT_DIR, 'var', 'media')
MEDIA_URL = '/media/'
and in your template file refer to the image like:
<img src="{{MEDIA_URL}}{{ case.zoomOutImage }}" width="100%">
when your object given to the template is called case
about your question of the urls.
you should add this:
if settings.DEBUG:
urlpatterns += patterns('',
(r'', include('staticfiles.urls')),
)
and see the link above to the question about using css, it's the same problem, but there for finding the css files during development. It's all about the static file places.
import os
# get abspath
def rel(*x):
return os.path.join(os.path.abspath(os.path.dirname(__file__)), *x)
MEDIA_ROOT = rel('media')
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
STATIC_ROOT = '' #if only your static files are in project folder
STATICFILES_DIRS = ( rel('static'),) #if only your static files are in project folder
use this settings, and everything will work
so i finally solved my problem. For anyone having this issue in the future do the following:
if you're trying to serve static media files locally on the development server use absolute paths for MEDIA_ROOT and MEDIA_URL.