# Create a GeoNode project The [`geonode-project`](https://github.com/GeoNode/geonode-project/tree/4.1.x) repository contains a Django project **template** that allows us to create a brand new web project that _has GeoNode core as a dependency_. In simple words, using this project template, can customize our GeoNode instance without actually touching the core GeoNode code. Thanks to the power of Django, we can override **HTML templates**, **views**, and, within certain limits, the **models**. We'll be calling a **GeoNode project** (or _`geonode-project` instance_) which is a Django project created using the `geonode-project` template. In this section we will learn how to: - Create a new virtual environment for our `geonode-project` instance - Initialize a new geonode project called `my_geonode` - Modify the look-and-feel of the `my_geonode` project ## Create `my_geonode` Django project First of all, we need to create a new virtualenv based on Python 3.10: ```bash mkvirtualenv -p $(which python3.10) my_geonode ```
command output ```shell created virtual environment CPython3.8.10.final.0-64 in 385ms creator CPython3Posix(dest=/home/geonode-vm-321/.virtualenvs/my_geonode, clear=False, global=False) seeder FromAppData(download=False, pip=latest, setuptools=latest, wheel=latest, pkg_resources=latest, via=copy, app_data_dir=/home/geonode-vm-321/.local/share/virtualenv/seed-app-data/v1.0.1.debian.1) activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator virtualenvwrapper.user_scripts creating /home/geonode-vm-321/.virtualenvs/my_geonode/bin/predeactivate virtualenvwrapper.user_scripts creating /home/geonode-vm-321/.virtualenvs/my_geonode/bin/postdeactivate virtualenvwrapper.user_scripts creating /home/geonode-vm-321/.virtualenvs/my_geonode/bin/preactivate virtualenvwrapper.user_scripts creating /home/geonode-vm-321/.virtualenvs/my_geonode/bin/postactivate virtualenvwrapper.user_scripts creating /home/geonode-vm-321/.virtualenvs/my_geonode/bin/get_env_details (my_geonode) geonode-vm-321@geonodevm-3:~$ ```
Install the correct version of Django ```shell pip install Django==3.2.18 ```
command output ```shell Collecting Django==3.2.18 Downloading Django-3.2.15-py3-none-any.whl (7.9 MB) |████████████████████████████████| 7.9 MB 6.5 MB/s Collecting pytz Downloading pytz-2021.3-py2.py3-none-any.whl (503 kB) |████████████████████████████████| 503 kB 6.3 MB/s Collecting sqlparse>=0.2.2 Downloading sqlparse-0.4.2-py3-none-any.whl (42 kB) |████████████████████████████████| 42 kB 1.2 MB/s Collecting asgiref<4,>=3.3.2 Downloading asgiref-3.5.0-py3-none-any.whl (22 kB) Installing collected packages: pytz, sqlparse, asgiref, Django Successfully installed Django-3.2.15 asgiref-3.5.0 pytz-2021.3 sqlparse-0.4.2 ```
The new VirtualEnv called `my_geonode` is now ready to be used. Let's create the target folder with the right permissions for the geonode project: ```shell cd /opt sudo mkdir geonode-project sudo chown -Rf $USER: geonode-project/ cd geonode-project/ ``` Now clone the `geonode-project` template from the repository: ```shell git clone https://github.com/GeoNode/geonode-project.git -b 4.1.x ``` Create the `my_django` project by using the `geonode-project` as a template: ```shell django-admin startproject --template=./geonode-project -e py,sh,md,rst,json,yml,ini,env,sample,properties -n monitoring-cron -n Dockerfile my_geonode ``` The previous command line should create a new folder called `my_geonode` that contains a Django project instance
Content of "my_geonode/src" directory ```shell /opt/geonode-project/my_geonode/src$ ll total 152 drwxrwxr-x 6 geonode-vm-321 geonode-vm-321 4096 Mar 16 17:42 ./ drwxrwxr-x 4 geonode-vm-321 geonode-vm-321 4096 Mar 16 17:42 ../ -rwxrwxr-x 1 geonode-vm-321 geonode-vm-321 1280 Mar 16 17:42 celery-cmd* -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 540 Mar 16 17:42 celery.sh -rwxrwxr-x 1 geonode-vm-321 geonode-vm-321 2578 Mar 16 17:42 entrypoint.sh* drwxrwxr-x 2 geonode-vm-321 geonode-vm-321 4096 Mar 16 17:42 fixtures/ -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 506 Mar 16 17:42 jetty-runner.xml -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 559 Mar 16 17:42 Makefile -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 52 Mar 16 17:42 manage_dev.sh.sample -rwxrwxr-x 1 geonode-vm-321 geonode-vm-321 1092 Mar 16 17:42 manage.py* -rwxrwxr-x 1 geonode-vm-321 geonode-vm-321 77 Mar 16 17:42 manage.sh* -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 256 Mar 16 17:42 monitoring-cron drwxrwxr-x 5 geonode-vm-321 geonode-vm-321 4096 Mar 16 17:42 my_geonode/ <------- Django main app folder drwxrwxr-x 3 geonode-vm-321 geonode-vm-321 4096 Mar 16 17:42 package/ -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 39745 Mar 16 17:42 pavement.py -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 40 Mar 16 17:42 paver_dev.sh.sample -rwxrwxr-x 1 geonode-vm-321 geonode-vm-321 31 Mar 16 17:42 paver.sh* -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 13 Mar 16 17:42 README.md -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 160 Mar 16 17:42 requirements.txt <------- GeoNode/Django dependencies drwxrwxr-x 3 geonode-vm-321 geonode-vm-321 4096 Mar 16 17:42 scripts/ -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 1642 Mar 16 17:42 setup.py -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 22868 Mar 16 17:42 tasks.py -rw-rw-r-- 1 geonode-vm-321 geonode-vm-321 2447 Mar 16 17:42 uwsgi.ini -rwxrwxr-x 1 geonode-vm-321 geonode-vm-321 691 Mar 16 17:42 wait-for-databases.sh* ```
By taking a look into the `/opt/geonode-project/my_geonode/src/my_geonode` you should be able to recognize a standard Django app structure ```shell drwxrwxr-x 5 geonode geonode 4096 Sep 9 15:43 ./ drwxrwxr-x 7 geonode geonode 4096 Sep 9 15:43 ../ -rw-rw-r-- 1 geonode geonode 1279 Sep 9 15:43 apps.py drwxrwxr-x 2 geonode geonode 4096 Sep 9 15:43 br/ -rw-rw-r-- 1 geonode geonode 1356 Sep 9 15:43 celeryapp.py -rw-rw-r-- 1 geonode geonode 1042 Sep 9 15:43 __init__.py -rw-rw-r-- 1 geonode geonode 5000 Sep 9 15:43 settings.py <------- Django settings drwxrwxr-x 6 geonode geonode 4096 Sep 9 15:43 static/ drwxrwxr-x 2 geonode geonode 4096 Sep 9 15:43 templates/ <------- HTML templates -rw-rw-r-- 1 geonode geonode 1234 Sep 9 15:43 urls.py <------- main URL patterns -rw-rw-r-- 1 geonode geonode 1779 Sep 9 15:43 version.py -rw-rw-r-- 1 geonode geonode 1980 Sep 9 15:43 wsgi.py ``` Some files are still missing (like the **views**, **models**, and **migrations**) since they are not needed by default. ### Install dependencies We need to install the GeoNode project dependencies first. The default `requirements.txt` file contains two dependencies, which are - core GeoNode - `geonode_mapstore_client`: the adapter for using mapstore in GeoNode Performing a `pip install -r requirements.txt` would install these sources inside the virtual environment hidden directory, but we need our copy of the sources to be installed (remember, we need a setup for developers!) Edit the file `/opt/geonode-project/my_geonode/src/requirements.txt` and comment out the line ``` cd /opt/geonode-project/my_geonode/src vim requirements.txt ``` ```diff --- requirements.txt 2022-07-25 12:40:54.883782750 +0100 +++ requirements.txt 2022-07-25 13:15:59.807862863 +0100 @@ -1,2 +1,3 @@ -# -e git+https://github.com/GeoNode/geonode-mapstore-client.git@4.1.x#egg=django_geonode_mapstore_client +-e git+https://github.com/GeoNode/geonode-mapstore-client.git@4.1.x#egg=django_geonode_mapstore_client +#GeoNode==4.0.3 +-e /opt/geonode ``` Then install the other listed requirements: ```shell workon my_geonode pip install -r /opt/geonode-project/my_geonode/src/requirements.txt ``` This will install the local GeoNode and a copy of the geonode-mapstore-client in development mode As part of the GeoNode setup, you need to manually install some requirements that are bound to the locally installed binary packages: ```shell pip install pygdal=="`gdal-config --version`.*" ``` Finally, install the current app in dev mode ```shell cd /opt/geonode-project/my_geonode/src/ pip install -e . ``` ```shell # Ensure the NGINX and UWSGI services have been stopped sudo systemctl stop nginx sudo pkill -9 -f uwsgi sudo ps aux | grep uwsgi ``` - Let's edit the project `.env` in order to match the dev environment ### Configuration The GeoNode settings are configurable using environment variables. There is a sample file containing the most common variables that may need to be customized. Copy that sample file into the file we are going to edit: ```shell # Ensure we are in the correct virtualenv and folder workon my_geonode cd /opt/geonode-project/my_geonode/src cp ../.override_dev_env.sample ../.override_dev_env ``` Also, copy the sample files used to run the admin commands: ```shell cd /opt/geonode-project/my_geonode/src/ cp paver_dev.sh.sample paver_dev.sh cp manage_dev.sh.sample manage_dev.sh cp ../dev_config.yml . chmod +x paver_dev.sh manage_dev.sh ``` Edit the `.override_dev_env` file ```bash cd /opt/geonode-project/my_geonode/src vim ../.override_dev_env ``` Make sure the database info is correct and add the following line ```bash export ASYNC_SIGNALS=False ``` This is a recap of the edited lines: ```shell (my_geonode) geonode@geonode-32x-vm:/opt/geonode-project/my_geonode$ diff -u --color .override_dev_env.sample src/.override_dev_env ``` ```diff --- ../.override_dev_env.sample 2022-03-17 16:37:38.211554417 +0000 +++ ../.override_dev_env 2022-03-17 17:03:35.357738873 +0000 @@ -7,13 +7,13 @@ export GEONODE_INSTANCE_NAME=geonode export DJANGO_SETTINGS_MODULE=my_geonode.settings -export GEONODE_DATABASE=my_geonode +export GEONODE_DATABASE=geonode export GEONODE_DATABASE_PASSWORD=geonode -export GEONODE_GEODATABASE=my_geonode_data +export GEONODE_GEODATABASE=geonode_data export GEONODE_GEODATABASE_PASSWORD=geonode -export DATABASE_URL=postgis://my_geonode:geonode@localhost:5432/my_geonode -export GEODATABASE_URL=postgis://my_geonode_data:geonode@localhost:5432/my_geonode_data +export DATABASE_URL=postgis://geonode:geonode@localhost:5432/geonode +export GEODATABASE_URL=postgis://geonode:geonode@localhost:5432/geonode_data export DEFAULT_BACKEND_DATASTORE=datastore export GEOSERVER_WEB_UI_LOCATION=http://localhost:8080/geoserver/ @@ -94,3 +94,5 @@ export EXIF_ENABLED=True export CREATE_LAYER=True export FAVORITE_ENABLED=True + +export ASYNC_SIGNALS=False ``` ### Align the DB and GeoNode ```shell workon my_geonode cd /opt/geonode-project/my_geonode/src ./manage_dev.sh makemigrations ./manage_dev.sh migrate ``` Align the internal URLs and Metadata links ```shell # The order is important! Those are regex expressions and will be executed one after the other... # Fix GeoServer URLs first ./manage_dev.sh migrate_baseurl --source-address=http://localhost/geoserver --target-address=http://localhost:8080/geoserver # Fix GeoNode URLs ./manage_dev.sh migrate_baseurl --source-address=http://localhost/ --target-address=http://localhost:8000/ # Align the Metadata links ./manage_dev.sh set_all_datasets_metadata -d -p ``` ### Run GeoNode Finally, start `my_geonode` with either ```shell ./manage_dev.sh runserver 0.0.0.0:8000 ``` or (run in the background) ```shell ./paver_dev.sh start_django ``` - **Notice** how we don't need to fix the GeoServer `OAuth2` endpoints since we already did that in the previous section - Open the browser and go to the location `http://localhost:8000` - The main page and theme have been changed again ![image](img/132838719-068a6cd4-65df-43b7-81b0-853293b628b3.png) #### [Next Section: Customize a geonode project model](055_project_customize_model.md)