django project root self discovery - django

Ok so I recall there are some commands you could put in the settings.py file so that basically when you move your django project to another directory it won't get foo-bar'd up.
I know I could just do this by having a string variable everywhere it mentions the home directory but is there a more elegant way of doing this?

The architecture of a project in Django
root/
app1/
app2/
...
main/
settings.py
Inside settings.py:
SITE_ROOT = os.path.dirname(os.path.realpath(__file__)) -> gives the path of the file settings.py: root/main/. This is NOT THE ROOT OF THE PROJECT
PROJECT_PATH = os.path.abspath(os.path.dirname(__name__)) -> gives the root of the project: root/. This is THE ROOT OF THE PROJECT.

Django 1.8 already includes the project root directory as BASE_DIR:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
And you can use it in your app by importing settings:
from django.conf import settings
...
...
print(settings.BASE_DIR)

Grab the __file__ global, and use the various functions in os.path on it.
import os.path
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))

PROJECT_PATH = os.path.abspath(os.path.dirname(__name__))

Related

How to read shapefile in Django view helper function?

As part of my view logic I need to check if Latitude and Longitude points are withing city boundaries.
To do that, I am using city shapefiles with geopandas. It all works ok locally in plain python code.
However, when I run the following code in Django:
LA_geo_df = gpd.read_file('./City_Boundaries/City_Boundaries.shp')
I get the error:
DriverError at /
./City_Boundaries/City_Boundaries.shp: No such file or directory
What is the proper Django way of loading such files?
Auto-generated Django settings file will have a BASE_DIR setting that looks like this
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
This is an absolute file path to the root of your Django app. You can use this setting to build an absolute path to your file
CITY_BOUNDARIES_FILE_PATH = os.path.join(BASE_DIR, 'City_Boundaries', 'City_Boundaries.shp')
Then where you want to load the file you can use the setting
from django.conf import settings
LA_geo_df = gpd.read_file(settings.CITY_BOUNDARIES_FILE_PATH)

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)

Django settings: How to access variables from the settings folder in an app

I have a Django project with the following structure:
--|src
--project
--|settings
--__init__.py
--production.py
--local.py
--|app1
In my app I import the settings (from django.conf import settings) and then as I was following a tutorial they said to do this getattr(settings, VARIABLE). That doesn't work for me. Instead I can do this: settings.VARIABLE. What's the difference?
Oh and I ran type(settings) and it outputted <class 'django.conf.LazySettings'>.
in order to access variables in settings.py file, you can do like this:
for example, I define STATIC_ROOT variable in settings.py file like this:
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'static', 'static_root')
and I can access to this variable like this:
from django.conf import settings
document_root=settings.STATIC_ROOT
The difference is that for various reasons (see the documentation for details), the settings object is not loaded unless an object is referenced from it.
The LazySettings object is special and you have to access it with settings.SOMETHING.
The reason its called "Lazy" is because the entire object is not loaded and made available to you when you import it. This LazySettings object acts like a proxy to the actual settings object.
project DIR
--|app DIR
--|settings.py <<< your variable API_KEY = '28234-jns-23-23n'
from app.settings import API_KEY

Django default settings 1.6 BASE_DIR acting up

In the new template for settings django 1.6 generates the following code:
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
However this has never worked for me and I keep changing it to
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
Is their code wrong or am I missing something? The idea of this BASE_DIR is to avoid hardcoding dir names.
The idea behind os.path.dirname(os.path.dirname(__file__)) is to get two directories above your settings directory.
Your code os.path.abspath(os.path.dirname(__file__)) is the same as os.path.dirname(__file__).
You probably changed where your settings.py resides and for that you must change its path.

PyCharm does not resolve templates nor template tags nor statics in Django project

PyCharm does not find templates, nor template tags, nor static files in my Django project even though the project itself is set up right and working.
I am using Django 1.6.2 with this layout:
proj
.devtmp
manage.py
proj
settings.py
app1
templatetags
app2
templates
static
and with settings like these:
from os.path import join, dirname, pardir, abspath
PROJECT_ROOT = abspath(join(dirname(__file__), pardir))
DEV_TMP_DIR = join(PROJECT_ROOT, pardir, '.devtmp')
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
TEMPLATE_DIRS = (
join(PROJECT_ROOT, 'templates'),
)
MEDIA_ROOT = join(DEV_TMP_DIR, 'media')
MEDIA_URL = '/media/'
STATIC_ROOT = join(DEV_TMP_DIR, 'static')
STATIC_URL = '/static/'
INSTALLED_APPS = (
...
'django.contrib.staticfiles',
...
'proj'
'proj.app1'
'app2'
)
Update:
In the IDE preferences, I have configured paths to the project root, settings.py and manage.py. In addition, I have configured the project interpreter (I am running the runserver from the IDE right now with no problems).
Please try this - it works for me for templates:
set templates directories in Python Template Languages -> Template directories
in Project Structure mark your apps as Source Folders
EDIT :
After a project structure reorganization I had problem with static files again. Setting destination of setting.py file in Django Support -> Settings resolved the issue.
Right click on the templates directory and "Mark Directory As" -> "Template Directory" and select template language as django
I've solved this problem by editing settings for Django framework, as seen on a picture.
You need to set up your project properly.
Django Set Up
In Preferences | Languages & Frameworks | Django, Enable Django Suport, set up the path to your project's root, settings.py file, and manage.py file:
Mark your templates directory as Templates
In File | Settings | Project Structure for Windows/Linux and
PyCharm | Preferences | Project Structure for macOS, choose the directory to be marked as a template root.
Click on Templates on Mark as.
Click on OK to apply the changes you made.
The issue for me was that I was doing this in my settings module:
INSTALLED_APPS = [*INSTALLED_APPS, "debug_toolbar"]
This caused PyCharm to think that debug_toolbar is the only app in the entire project. Declaring INSTALLED_APPS in the standard way solved it.