morlandi / django-ajax-datatable

A Django app which provides the integration of a Django project with the jQuery Javascript library DataTables.net
MIT License
211 stars 64 forks source link

JSONField keys as Fully Featured (sortable, orderable, filterable) Columns? #83

Open jareklupinski opened 2 years ago

jareklupinski commented 2 years ago

Thank you for your wonderful django-ajax-datatables repository! It has really helped me understand how to build efficient queries and snappy interfaces.

I was wondering if you could guide me towards the best way to add JSONField sorting and filtering support please? For example, if I have a 'jsondata' db column that contains {'repo': 'django-ajax-datables'}, I would like to create a column called 'Repos' which lets me filter those 'jsondata' database rows that have 'repo' == 'django-ajax-datatables' + 'django-task' :)

I am currently just kludging this in to display the data, but it is not sortable/filterable without using external input fields:

def render_column(self, row, column):
    if column == 'repo':
        data = row.jsondata
        if data:
            value = data.get('repo')
        else:
            value = None
    elif column == 'bliz':
        data = row.jsondata
        if data:
            value = data.get('bliz')
        else:
            value = None
    else:
        value = self.column_obj(column).render_column(row)
    return value

I tried putting in a JSONFieldColumn that subclasses Column, but I ran into an issue subclassing a Class with an over-ridden function, probably just my misunderstanding of Python inheritance but my attempt at adding this did not work correctly:

def column_factory(model, column_spec):
    """
    Build either a Column or a ForeignColumn as required
    """
    fields = {f.name: f for f in model._meta.get_fields()}
    col_name = column_spec['name']
    sort_field = column_spec['sort_field']
    foreign_field = column_spec.get('foreign_field', None)
    m2m_foreign_field = column_spec.get('m2m_foreign_field', None)
    json_field = column_spec.get('json_field', None)

    if foreign_field:
        new_column = ForeignColumn(col_name, model, foreign_field)
    elif m2m_foreign_field:
        new_column = ManyToManyColumn(col_name, model, m2m_foreign_field)
    elif json_field:
        new_column = JSONFieldColumn(col_name, model, json_field)
    elif col_name in fields:
        new_column = Column(fields[col_name], sort_field=sort_field)
    else:
        new_column = Column(col_name, sort_field=sort_field)
    return new_column