Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I think something like this is feasible but making it universal (allowing full read-only access to the ORM) would be very difficult to make in a secure way.</p> <p>Here are some ideas:</p> <p>Limit the actions to a predefined set of explicitly marked methods on a custom manager class. For example:</p> <pre><code>from django.db import models class MarkupAccessManager(models.Manager): def count(self): return super(MarkupAccessManager, self).count() count.expose_to_markup = True class AfricanSwallow(models.Model): objects = MarkupAccessManager() </code></pre> <p>To refer to models from the markup, you could take advantage of the <code>django.contrib.contenttypes</code> framework and the tags could have the following format: <code>app_label.model_name action</code> or <code>app_label.model_name action arg1 arg2</code>.</p> <p>Depending on the markup language you choose, you could either use custom tags (if the language provides them), Django template tags, or plain regular expressions. Once you get the contents of a tag, this is how you could replace it with the output of the referred method:</p> <pre><code>from django.contrib.contenttypes.models import ContentType def replace_tag(tag): """ 'birds.africanswallow count' =&gt; birds.models.AfricanSwallow.objects.count() """ bits = tag.split() model_ref = bits[0] action = bits[1] args = bits[2:] try: ct = ContentType.objects.get_by_natural_key(*model_ref.split('.')) except ContentType.DoesNotExist: return 'Invalid model reference.' model = ct.model_class() method = getattr(model._base_manager, action, None) if not method or not method.expose_to_markup: return 'Invalid action.' return method(*args) </code></pre> <p>To provide autocomplete, something along these lines would help you to build a list of all the available options:</p> <pre><code>from django.db.models.loading import get_models from django.contrib.contenttypes.models import ContentType def model_refs(): for model in get_models(): if isinstance(model._base_manager, MarkupAccessManager): ct = ContentType.objects.get_for_model(model) yield '%s.%s' % (ct.app_label, ct.model) def actions(): for attr_name in dir(MarkupAccessManager): attr = getattr(MarkupAccessManager, attr_name) if attr.expose_to_markup: yield attr.__name__ </code></pre> <p>I haven't tested the code. Hope this helps a bit.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload