How to read shapefile in Django view helper function? - django

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)

Related

Access python script from one project to another

Main folder
|-project1
|-project2
I have the above structure for django projects.
When I am in project1 in a script i used os.chdir(to_project2) to project 2
I want to access project2's settings.py and fetch some attributes. Is it possible?
#You need to point your directory.[Ex: project2]
import os
os.chdir(project2 )
cd = os.getcwd()
# print the current directory
print("Current directory:", cwd)
#For Access the Django setting attributes
import django
from django.conf import settings
All of those aforementioned code you may use from one of your python file: something.py

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 model cannot find a static file

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

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.

django project root self discovery

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__))