Diseño de aplicaciones de metadatos¶
La idea es utilizar un estándar bien establecido para documentar el esquema de metadatos y devolver la información de metadatos.
El esquema de metadatos se presenta utilizando las convenciones Esquema JSON.
La API de GeoNode se ha ampliado para proporcionar:
/api/v2/metadata/schemaesquema de metadatos/api/v2/metadata/instancia/<PK |UUID>manejo de instancias de metadatos de recursos (GET/PUT)/api/v2/metadata/<...>otras llamadas de utilidad para el manejo de metadatos (autocompletar puntos finales referidos al esquema, etc.)
Una de las características básicas de conducción ha sido la simplificación de la personalización del esquema.La implementación se basa en un conjunto de controladores de metadatos que se pueden ampliar fácilmente.
El módulo opcional geonode-inspire es una muestra de trabajo que documenta cómo se puede personalizar el modelo base de GeoNode.
Implementación¶
El paquete geonode.metadata contiene todo el código relacionado con el manejo de metadatos.
El módulo manager contiene el motor base que llama a métodos en los controladores de campo registrados.
Descripción general de los controladores¶
Controladores son los objetos que gestionan el ciclo de vida del campo, es decir:
cree el json subesquema del campo
encargarse de cargar datos de la base de datos y convertirlos en una instancia de esquema json
analizar el valor de la instancia del esquema json enviado desde el cliente y almacenarlo en el formato de la base de datos
Un único controlador puede manejar uno o más campos.
Administrador de metadatos¶
La clase geonode.metadata.manager.MetadataManager maneja las solicitudes de la vista y delega el trabajo en los campos a los controladores declarados.
MetadataManager proporciona estos métodos principales:
def get_schema(self, lang=None)
Crea y devuelve el esquema json de metadatos.
Este método es llamado por el punto final /api/v2/metadata/schema.
El esquema se crea haciendo un bucle en el conjunto ordenado de controladores de metadatos, pidiéndoles que actualicen el esquema json de forma incremental a través de def update_schema(self, jsonschema: dict, context, lang=None).
Los controladores pueden agregar su propio campo, eliminar o modificar campos agregados por controladores previamente llamados.
La localización del esquema solo está relacionada con las anotaciones «título» y «descripción».La localización de listas desplegables es una tarea específica del controlador y generalmente se lleva a cabo a través de listas de códigos de tesauros (ver tesauro).
El idioma predeterminado utilizado es el establecido en las cookies, o se puede anular agregando el parámetro de consulta lang.
def build_schema_instance(self, resource: ResourceBase, lang=None)
Crea y devuelve la instancia del esquema json relacionada con un recurso.
La instancia se crea examinando el esquema json y realizando un bucle en cada campo.Para cada campo, se llama al controlador relacionado para completar el valor serializado de dicho campo.
Métodos de controladores llamados:
def load_serialization_context(resource: ResourceBase, jsonschema: dict, context: dict)Permitir que un controlador precargue información común para todos sus campos manejadosdef get_jsonschema_instance(recurso: ResourceBase, nombre_campo, contexto, errores, lang=None)Devuelve la instancia del subesquema asociado con el campo nombre_campo.
def update_schema_instance(self, resource, request_obj, lang=None) -> dict:
Analiza la instancia del esquema json entrante y almacena el valor en la base de datos.
La persistencia se logra examinando el esquema json y realizando un bucle en cada campo.Para cada campo, se llama al controlador relacionado para analizar y almacenar los valores deserializados para dicho campo.Si el campo es un objeto complejo, depende del controlador analizarlo y manejarlo.
Métodos de controladores llamados:
def load_deserialization_context(self, recurso: ResourceBase, jsonschema: dict, contexto: dict)Permitir a los controladores precargar información común para todos los campos manejadosdef update_resource(recurso: ResourceBase, nombre_campo: str, json_instance: dict, contexto: dict, errores: dict, **kwargs)Lógica para analizar y conservar el campo
Handlers¶
La lista de controladores se declara en geonode.metadata.settings.METADATA_HANDLERS.
El orden es importante ya que los controladores declarados posteriormente pueden querer personalizar los campos definidos previamente.
Dentro de cada subesquema de campo hay algunas anotaciones específicas de geonode (el estándar de esquema json permite anotaciones personalizadas), algunas son necesarias para la lógica de backend (por ejemplo, geonode:handler), otras para la interfaz de usuario del cliente (por ejemplo, ui:options)
Manejador base¶
BaseHandler maneja la mayoría de los campos declarados dentro de la clase ResourceBase.
El BaseHandler leerá el esquema principal de un archivo (metadata/schemas/base.json), aumentando mediante programación cierta información que no se puede configurar estáticamente (como las URL de autocompletar).
Manejador disperso¶
Este controlador no lo utiliza activamente el esquema central de GeoNode, ya que está más dirigido a personalizaciones.
Es posible que vea un ejemplo de su uso en el paquete geonode-inspire.
La idea básica para SparseField (el cambio de modelo único en metadatos) es tener una tabla «vertical» con campos de formato libre:
ResourceBase y sus campos dispersos¶
En el caso por defecto su uso es tan sencillo como declarar el campo:
"prj1_distance": {
"type": "numeric"
}
o incluso una estructura compleja como
"prj1_instrumentations": {
"type": "array",
"title": "instrumentations",
"description": "Provides information about any instruments used in the data collection. The description should include vendor, model number, optional equipment, etc.",
"items": {
"type": "string",
"minLength": 1,
"default": ""
},
"minItems": 1,
"geonode:handler": "sparse"
}
Cuando el tipo es matriz u objeto, SparseHandler codificará todo el contenido como un objeto json
Algunas anotaciones personalizadas¶
geonode:handler: clave para el controlador definido enMETADATA_HANDLERS;indica cuál es el controlador que se llamará para manejar el contenido del campo.Tenga en cuenta que esta anotación puede ser reemplazada por controladores posteriores si desean manejar el campo de manera diferente.geonode:required: las especificaciones jsonschema quieren que la matrizrequiredesté fuera de la definición del subesquema.Al definir esta anotación como «verdadera», el administrador de metadatos agregará el campo actual en la lista «obligatoria».