pythondjangoopendap

Integrating a custom function in Django


I would like to access and print metadata (attributes and values) served by an ERDDAP server, which is a variety of OPeNDAP, on my Django website.

so I prepared a simple example function called get_conventions to access a metadata field on this public server hosting data and metadata. To get started, I install the required packages:

$ pip install pandas erddapy

and then,

import pandas as pd
from erddapy import ERDDAP

def get_conventions(dataset_id):
    e = ERDDAP(server='https://gliders.ioos.us/erddap/', protocol='tabledap', response='csv')
    url = e.get_info_url(dataset_id, response='csv')
    df = pd.read_csv(url)

    # this replace spaces with underscores in column names
    df.columns = [col_name.replace(' ', '_') for col_name in df.columns]

    conventions = df[df.Attribute_Name == 'Conventions'].Value
    return conventions

Using a Python interpreter, one could call the function like this with this sample dataset id as an argument (amelia-20180501T0000), which is found on the server; the output follows:

>>> get_conventions('amelia-20180501T0000')
6    Unidata Dataset Discovery v1.0, COARDS, CF-1.6
Name: Value, dtype: object
>>>

I would like my website to print on a webpage the output of the above function.

I can print the argument string in a page (model.py, views.py and a related html templates - those being similar to the Django tutorial), but I am unsure how to refer the argument to the function (and expect a return) or how/where to integrate the function in the Django structure.

The argument is stored in a local database which can be referred using models/views/template

But I am unsure how to integrate the part involving the function in Django?


Solution

  • I was able to make this work after reading this, by D. Patel.

    It involved adding the following to the file named services.py which was placed an app subfolder titled templatetags. This is where the get_conventions custom function reside:

    from django import template
    ...
    
    register = template.Library()
    
    
    @register.filter
    def get_conventions(dataset_id):
    ...
        return conventions
    

    and in the template, I had to load the services file and add the following to the html template:

    {% load services %}
    {% block content %}
        <p><strong>Conventions:</strong> {{ station.dataset_id | get_conventions }}</p>
    ...
    {% endblock %}
    

    station.dataset_id being the argument for the get_conventions function paired | with the return value

    and it worked as intended. It was quite straightforward.