Django's find the path to setting.py - python

Until not long ago, I used to do this in many places in my Django app:
from MyApp import settings
This required that I put settings inside my MyApp directory. I realized that is wrong, so I started using:
from django.conf import settings
But now I can't figure out how to find the path to settings.py from withing my code. Earlier I could use settings.__file__.
As a workaround I defined inside settings.py:
PATHTOSELF = os.path.dirname(__file__)
Any ideas how to find the path to settings.py?

Try This:
import os
PROJECT_PATH = os.path.dirname(os.path.abspath(__file__))

This should work for you:
import os
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
Place it on top inside of your settings.py. You can then import PROJECT_ROOT at any point in your code like this:
from myapp.settings import PROJECT_ROOT

Related

MediaStorage doesn't look like a module path. Django Error

I am using AWS to host my media files from my django app. I am following this tutorial, and when I use the following code,
from storages.backends.s3boto import S3BotoStorage
class MediaStorage(S3BotoStorage):
location = 'media'
MEDIA_URL = "https://%s/media/" % (AWS_S3_CUSTOM_DOMAIN)
DEFAULT_FILE_STORAGE = 'MediaStorage'
I get this error:
MediaStorage doesn't look like a module path
I have know idea why. Any thoughts?
You have to set the full module path for DEFAULT_FILE_STORAGE. See sample from documentation
DEFAULT_FILE_STORAGE
Default: 'django.core.files.storage.FileSystemStorage'
So put MediaStorage class in a storage.py module (path project/storage.py) and point DEFAULT_FILE_STORAGE='project.storage.MediaStorage'

django view url mapping

I am trying to load a template from a nested directory in django but keep getting a improperly configured no pattern match error. I've attempted all combinations of folder names but the error keeps on continuing, I'm scratching my head with this one, any help? here are my files:
view.py
from django.http import HttpResponse
from django.template import loader
def index():
curTemplate = loader.get_template('/droneMapper/index.html')
return HttpResponse(curTemplate.render())
settings.py
BASE_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)
TEMPLATE_DIRS = (os.path.abspath(os.path.join(BASE_DIR, 'templates')),)
the file strcture is:
root
-app
-templates
-app
-setting
I simply use this small code:
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),)
works fine for me.

django settings per application - best practice?

this is somewhat related to this question
Why is django's settings object a LazyObject?
In my django project i have several applications. Each application can have its own non-trivial settings file.
proj/
proj/
settings.py
app/
settings.py
views.py
What is the general best practice here?
should app/settings.py do
from django.conf import settings
APP_SETTING= lambda: settings.getattr('APP_SETTING', 'custom_value')
PROJ_SETTING= lambda: settings.PROJ_SETTING
and then in app/views.py do
import .settings
X = settings.APP_SETTING
Y = settings.PROJ_SETTING
or should I be modifying the django lazy settings object in app/settings.py as per the django coding style?
from django.conf import settings
# not even sure how I would check for a default value that was specified in proj/settings.py
settings.configure(APP_SETTING='custom_value')
and then each app/views.py just consumes proj/settings.py via django.conf settings?
from django.conf import settings
X = settings.APP_SETTING
Y = settings.PROJ_SETTING
There are obviously quite a few other permutations but I think my intent is clear.
Thanks in advance.
The simplest solution is to use the getattr(settings, 'MY_SETTING', 'my_default') trick that you mention youself. It can become a bit tedious to have to do this in multiple places, though.
Extra recommendation: use a per-app prefix like MYAPP_MY_SETTING.
There is a django app, however, that gets rid of the getattr and that handles the prefix for you. See http://django-appconf.readthedocs.org/en/latest/
Normally you create a conf.py per app with contents like this:
from django.conf import settings
from appconf import AppConf
class MyAppConf(AppConf):
SETTING_1 = "one"
SETTING_2 = (
"two",
)
And in your code:
from myapp.conf import settings
def my_view(request):
return settings.MYAPP_SETTINGS_1 # Note the handy prefix
Should you need to customize the setting in your site, a regular entry in your site's settings.py is all you need to do:
MYAPP_SETTINGS_1 = "four, four I say"
Since Django 1.7 there is a django-based structure for app-oriented configurations!
You could find descriptive solution here
In this new structure, conventionally you could have an apps.py file in your applications' folder which are embeded in project, something like this:
proj/
proj/
settings.py
app1/
apps.py
views.py
app2/
apps.py
views.py
app1/apps.py file could include something like this:
from django.apps import AppConfig
class App1Config(AppConfig):
# typical systemic configurations
name = 'app1'
verbose_name = 'First App'
# your desired configurations
OPTION_A = 'default_value'
APP_NAMESPACE = 'APP'
APP_OPTION_B = 4
you could have app2/apps.py something different like this:
from django.apps import AppConfig
class App2Config(AppConfig):
# typical systemic configurations
name = 'app2'
verbose_name = 'Second App'
# your desired configurations
OTHER_CONFIGURATION = 'default_value'
OPTION_C = 5
and so etc for other apps.pys in you Django Application folder.
It's important that you should import applications you included apps.py in, as follows:
# proj/settings.py
INSTALLED_APPS = [
'app1.apps.App1Config',
'app2.apps.App2Config',
# ...
]
‌Now, You could access desired app-based configuration someway like this:
from django.apps import apps
apps.get_app_config('app1').OPTION_A
Not sure about best practices but I don't have any problems with following style:
proj/settings.py
OPTION_A = 'value'
# or with namespace
APP_NAMESPACE = 'APP'
APP_OPTION_B = 4
app/settings.py
from django.conf import settings
from django.utils.functional import SimpleLazyObject
OPTION_A = getattr(settings, 'OPTION_A', 'default_value')
# or with namespace
NAMESPACE = getattr(settings, APP_NAMESPACE, 'APP')
OPTION_B = getattr(settings, '_'.join([NAMESPACE, 'OPTION_B']), 'default_value')
OPTION_C = getattr(settings, '_'.join([NAMESPACE, 'OPTION_C']), None)
if OPTION_C is None:
raise ImproperlyConfigured('...')
# lazy option with long initialization
OPTION_D = SimpleLazyObject(lambda: open('file.txt').read())
app/views.py
from .settings import OPTION_A, OPTION_B
# or
from . import settings as app_settings
app_settings.OPTION_C
app_settings.OPTION_D # initialized on access
My site is just starting and I want a the simplest but flexible configuration solution. That's what I came across with.
# in the end of the site's settings.py
. . .
# Custom settings
MYAPP_CONFIG_FILE = "/home/user/config/myapp_config.ini"
In my application's models.py:
from django.conf import settings
import configparser
config = configparser.ConfigParser()
config.read(settings.MYAPP_CONFIG_FILE, encoding='utf_8')
This config parser is described here. It's convenient enough but definitely not the only option.
you can use django-zero-settings, it lets you define your defaults and a key for your user settings, then it will handle user overrides too.
it also auto imports your settings, has the ability to handle removed settings, and can pre-check settings too.
as an example, define your settings:
from zero_settings import ZeroSettings
app_settings = ZeroSettings(
key="APP",
defaults={
"TOKEN": "token"
},
)
then you can use it like:
from app.settings import app_settings
print(app_settings.TOKEN)

how to access settings variable from different project in the same folder in django

I have different projects under one folder in django. I am trying to get all caches variables from each settings.py to be displayed in one project A. So far, I have been able to access the local settings in A.
Using something like
<!-- language: lang-py -->
from django.conf import settings
def get_cache_settings():
return settings.CACHES.keys()
Then I tried the following to get the settings from B but didn't work
<!-- language: lang-py -->
from B.django.conf import settings
also tried
<!-- language: lang-py -->
from B import django.conf.settings
The tree folder look like this:
Project/
A/
cache/
urls.py
view.py
settings.py
B/
settings.py
Any suggestions?
Django settings are project level, so there is no such thing as app settings.
If you are talking about a settings.py file living in app directory A, just:
from A import settings as A_settings
What you need to do is add your bigger folder to your python path.
$export PYTHONPATH=..:$PYTHONPATH
now you can do
from A import settings as A_settings
from B import settings as B_settings

Unable to access file as a database in django

In my django application structure is as follows:
__init__.py
__init__.pyc
models.py
tests.py
usage.rrd
views.py
views.pyc
I am trying to access the usage.rrd file in views.py as follows:
from django.http import HttpResponse
import rrdtool
def hello(request):
info = rrdtool.info('usage.rrd')
return HttpResponse(info)
but I am getting:
opening '/usage.rrd': No such file or
directory
despite being in the current directory.
The application starts from the root directory of your project. So you you need to fix your path, ('app-name/usage.rrd') .
As mentioned in thebwt's answer it's a path issue. The working directory for your django environment will not be that of you app, hence the failure to locate your file.
You will have to specify either a full path to your rrd file (not ideal) or a path relative to the working directory.
Alternatively, a common trick to deal with issues like this is to extract the directory a particular python module is in (using __file__), and using that to translate a paths (relative to the current file) to an absolute path. For example:
FILE_DIR = os.path.realpath(os.path.dirname(__file__))
rel_to_abs = lambda *x: os.path.join(FILE_DIR, *x)
In your case:
# in view.py
import os
import rrdtools
FILE_DIR = os.path.realpath(os.path.dirname(__file__))
rel_to_abs = lambda *x: os.path.join(FILE_DIR, *x)
def hello(request):
info = rrdtool.info(rel_to_abs('usage.rrd'))
return HttpResponse(info)
p.s. you might have seen this method being used in settings.py to specify paths to sqlite3 DATABASE_NAME, MEDIA_ROOT, etc. such that the absolute path is obtained at runtime rather than being hardcoded.

Categories