django-sql-explorer
django-sql-explorer copied to clipboard
Embedding a query
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.