Customize a geonode project model¶
In this section, we will patch the ResourceBase
of GeoNode
and update the templates
in order to add one more field to the Metadata Schema
.
We will add a custom_md
field to the ResourceBase
model and modify the templates in order to show the new field both into the Metadata Wizard
and the Layer Details
page.
Activate the virtualenv¶
We should already be working in the right directory, and with the proper venv activated. If not, run:
workon my_geonode
cd /opt/geonode-project/my_geonode/
Update the GeoNode
ResourceBase
model
vim /opt/geonode/geonode/base/models.py
{% raw %}
diff --git a/geonode/base/models.py b/geonode/base/models.py
index e2a5a409c..922c67db4 100644
--- a/geonode/base/models.py
+++ b/geonode/base/models.py
@@ -706,6 +706,7 @@ class ResourceBase(PolymorphicModel, PermissionLevelMixin, ItemBase):
data_quality_statement_help_text = _(
'general explanation of the data producer\'s knowledge about the lineage of a'
' layer')
+ custom_md_help_text = _('a custom metadata field')
# internal fields
uuid = models.CharField(max_length=36)
title = models.CharField(_('title'), max_length=255, help_text=_(
@@ -959,6 +960,13 @@ class ResourceBase(PolymorphicModel, PermissionLevelMixin, ItemBase):
__is_approved = False
__is_published = False
+
+ custom_md = models.TextField(
+ _("Custom Md"),
+ blank=True,
+ null=True,
+ help_text=custom_md_help_text)
+
objects = ResourceBaseManager()
class Meta:
{% endraw %}
Add the new field to the DB
./manage_dev.sh makemigrations
./manage_dev.sh migrate
Add the new field to
templates
mkdir my_geonode/templates/layouts/
cp /opt/geonode/geonode/layers/templates/layouts/panels.html my_geonode/templates/layouts/panels.html
vim my_geonode/templates/layouts/panels.html
{% raw %}
--- /opt/geonode/geonode/layers/templates/layouts/panels.html 2021-09-01 14:22:59.778823091 +0100
+++ my_geonode/templates/layouts/panels.html 2021-09-10 15:48:39.691395977 +0100
@@ -317,6 +317,10 @@
</div>
{% endblock thumbnail %}
<div class="col-lg-4">
+ <div id="req_item">
+ <span><label for="{{ layer_form.custom_md|id }}">{{ layer_form.custom_md.label }}</label></span>
+ {{ layer_form.custom_md }}
+ </div>
{% block layer_title %}
<div id="req_item">
<span><label for="{{ layer_form.title|id }}">{{ layer_form.title.label }}</label></span>
{% endraw %}
Let’s check the changes
./paver_dev.sh start_django
Update the
custom_md
text field to arich HTML
one
vim /opt/geonode/geonode/base/forms.py
{% raw %}
diff --git a/geonode/base/forms.py b/geonode/base/forms.py
index 48a0ef7f1..e0284988c 100644
--- a/geonode/base/forms.py
+++ b/geonode/base/forms.py
@@ -416,6 +416,10 @@ class ResourceBaseForm(TranslationModelForm):
label=_("Data quality statement"),
required=False,
widget=TinyMCE())
+ custom_md = forms.CharField(
+ label=_("Custom Md"),
+ required=True,
+ widget=TinyMCE())
owner = forms.ModelChoiceField(
empty_label=_("Owner"),
{% endraw %}
Update the Layers Details Templates¶
Copy the default GeoNode
layer_details
template
mkdir my_geonode/templates/layers
cp /opt/geonode/geonode/layers/templates/layers/layer_detail.html my_geonode/templates/layers/layer_detail.html
Add the new field to the
layer_details
template
vim my_geonode/templates/layers/layer_detail.html
mkdir my_geonode/templates/base
cp /opt/geonode/geonode/base/templates/base/resourcebase_info_panel.html my_geonode/templates/base/resourcebase_info_panel.html
vim my_geonode/templates/base/resourcebase_info_panel.html
cp /opt/geonode/geonode/base/templates/base/_resourcebase_info_panel.html my_geonode/templates/base/_resourcebase_info_panel.html
vim my_geonode/templates/base/_resourcebase_info_panel.html
{% raw %}
--- /opt/geonode/geonode/base/templates/base/_resourcebase_info_panel.html 2021-07-14 14:38:25.391987680 +0100
+++ my_geonode/templates/base/_resourcebase_info_panel.html 2021-09-13 09:47:42.768337828 +0100
@@ -31,6 +31,11 @@
<dd itemprop="description">{{ resource.abstract|safe }}</dd>
{% endif %}
+ {% if resource.custom_md %}
+ <dt>{% trans "Custom Metadata" %}</dt>
+ <dd itemprop="description">{{ resource.custom_md|safe }}</dd>
+ {% endif %}
+
{% if resource.date %}
{% if resource.date_type == 'creation' %}
<dt>{% trans "Creation Date" %}</dt>
{% endraw %}
API REST (v2)¶
Let’s add the new
custom_md
field to theREST API
of GeoNodeThe APIs are reachable through the endpoint:
http://localhost:8000/api/v2/
Looking at the
http://localhost:8000/api/v2/resources
you will notice that the new field we just added is not visibleModify the GeoNode
base
rest api endpoints in order to add the new field
vim /opt/geonode/geonode/base/api/serializers.py
{% raw %}
diff --git a/geonode/base/api/serializers.py b/geonode/base/api/serializers.py
index c1a5e8679..909aca07e 100644
--- a/geonode/base/api/serializers.py
+++ b/geonode/base/api/serializers.py
@@ -293,6 +293,7 @@ class ResourceBaseSerializer(BaseDynamicModelSerializer):
self.fields['raw_data_quality_statement'] = serializers.CharField(read_only=True)
self.fields['metadata_only'] = serializers.BooleanField()
self.fields['processed'] = serializers.BooleanField(read_only=True)
+ self.fields['custom_md'] = serializers.CharField()
self.fields['embed_url'] = EmbedUrlField()
self.fields['thumbnail_url'] = ThumbnailUrlField()
@@ -325,7 +326,8 @@ class ResourceBaseSerializer(BaseDynamicModelSerializer):
'popular_count', 'share_count', 'rating', 'featured', 'is_published', 'is_approved',
'detail_url', 'embed_url', 'created', 'last_updated',
'raw_abstract', 'raw_purpose', 'raw_constraints_other',
- 'raw_supplemental_information', 'raw_data_quality_statement', 'metadata_only', 'processed'
+ 'raw_supplemental_information', 'raw_data_quality_statement', 'metadata_only', 'processed',
+ 'custom_md'
# TODO
# csw_typename, csw_schema, csw_mdsource, csw_insert_date, csw_type, csw_anytext, csw_wkt_geometry,
# metadata_uploaded, metadata_uploaded_preserve, metadata_xml,
{% endraw %}
http://localhost:8000/api/v2/resources?filter{custom_md.isnull}=False
More info about
dynamic-rest
filtering options can be found at:https://github.com/AltSchool/dynamic-rest#filtering