Skip to content

Embedding a query #485

@spapas

Description

@spapas

Hello friends, in a recent project I wanted to embed a query in a view for all users to be able to run it. So instead of using the provided views I wanted to properly embed the report in my views so as to use my permissions etc (the requirement was a little more complex than that but it doesn't matter).

I didn't find any docs for that so I had to research the source code and use the query_viewmodel function. So, my query detail view is similar to this:

from explorer.models import Query
from explorer.views.utils import query_viewmodel

class QueryDetailView(DetailView):
    template_name = "reports/query_detail.html"
    model = Query

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        query = self.get_object()
        query.params = dict(
            [(k[:-6], v) for k, v in self.request.GET.items() if k.endswith("_param")]
        )

        vm = query_viewmodel(self.request, query)

        # dict_keys(['tasks_enabled', 'params', 'title', 'shared', 'query', 'form', 'message', 'error', 'rows', 'data', 'headers', 'total_rows', 'duration', 'has_stats', 'snapshots', 'ql_id', 'unsafe_rendering', 'fullscreen_params'])
        context.update(vm)
        context["title"] = query.title
        return context

Then I used a query_detail.html template like:

{% extends "site_base.html" %}
{% block page_content %}

{% if params %}
<form method='GET'>
    <div class="form-inline">
        {% for k, v in params.items %}
            <div class="form-group">
                <label for="{{ k }}_param" class="control-label col-sm-4">{{ k }}:</label>
                <div class="col-sm-7">
                    <input type="text" data-param="{{ k }}" class="param form-control" name="{{ k }}_param" id="{{ k }}_param" placeholder="parameter" value="{{ v }}" />
                </div>
                <div class="col-sm-1"></div>
            </div>
        {% endfor %}
    </div>
    <input type='submit' class='btn btn-primary' value='Query'>
    <a href='{{ request.path }}' class='btn btn-secondary'>Reset</a>
</form>
{% endif %}

<div class="row">
    <div class="col-md-12">
        {% if data %}
            <table class='table'>
                <thead>
                    <tr>
                        {% for col in headers %}
                            <th>{{ col }}</th>
                        {% endfor %}
                    </tr>
                </thead>
                <tbody>
                    {% for row in data %}
                        <tr>
                            {% for col in row %}
                                <td>{{ col }}</td>
                            {% endfor %}
                        </tr>
                    {% endfor %}
                </tbody>
            </table>
        {% endif %}
    </div>
</div>
{% endblock %}

I'm not sure if this is the correct way to do it, can you please confirm. If yes, I'd recommend adding this in the documentation so it's easy for other users that want to embed queries. Also we may want to make the query_viewmodel function as part of the API so we should describe its inputs/outputs.

I can provide the PR with the change to the docs if you think it will be useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions