I'm looking for functionality vaguely like that provided by Semantic MediaWiki. In short, I'd like for a user, in an arbitrary text field, to be able to do things like the following (I'm making up the markup as I go).
*Hi, everyone, don't forget that we have [[::AfricanSwallow.count]] African Swallows in our land.
*Did you know that Harry the European Swallow has carried [[::EuropeanSwallow.get(name="harry").coconuts.count]] coconuts back with him?
In addition to these kinds of features, I'd like to be able to autocomplete inline - perhaps when the user starts typing.
I can do all of these things, but I'm hoping that some or all of them have been done. Any idea if that's the case?
models import User class InputUserInfo(forms. Form): phone = forms. CharField(max_length=20) instagram = forms. CharField(max_length=20) facebook = forms.
The __str__ method in Python represents the class objects as a string – it can be used for classes. The __str__ method should be defined in a way that is easy to read and outputs all the members of the class. This method is also used as a debugging tool when the members of a class need to be checked.
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.
Here are some ideas:
Limit the actions to a predefined set of explicitly marked methods on a custom manager class. For example:
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()
To refer to models from the markup, you could take advantage of the django.contrib.contenttypes
framework and the tags could have the following format: app_label.model_name action
or app_label.model_name action arg1 arg2
.
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:
from django.contrib.contenttypes.models import ContentType
def replace_tag(tag):
"""
'birds.africanswallow count' => 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)
To provide autocomplete, something along these lines would help you to build a list of all the available options:
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__
I haven't tested the code. Hope this helps a bit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With