Highlighting custom model field in django template

I extended django-markdown

with a custom model field that allows classes to be defined:

from django.db import models
from django_markdown.fields import MarkdownField

class MyModel(models.Model):
    text = MarkdownField()

class MySecondModel(models.Model):
    description = MarkdownField()

      

Now when it comes to rendering these fields in the template, you can do:

{% load markdown_tags %}
{{ model.text|markdown }} {{ model2.description|markdown }}

      

However, this seems to defeat the custom model field creation object first (to enhance drying) and is advisable to be avoided at all costs.

So, is there a way to do it just {{ model.text }} {{ model2.description }}

without loading template tags and without filtering by defining a method render

on a custom field?

A similar question has already been asked: Is there a way to customize how the value for a custom model field is displayed in the template? but the answer entails adding a method to the model. This would mean adding methods to MyModel

and MySecondModel

, as well as any subsequent ones. Again, this defeats the entire DRY object!

NB Both model classes are subclasses of something else, so defining a mix is โ€‹โ€‹possible, but certainly should be better!

+3


source to share


1 answer


I am in the same situation as you. I figured I could solve it using a mixin for the Model class.

It seems to work as intended, but I'm not sure if it did it correctly. Feels like a dirty hack that I don't quite understand.



You should, of course, replace the _shout () method with something more useful.

from django.utils.safestring import mark_safe
from django.db import models


class LoudModelMixin(object):

    """ adds the 'html' property to a Model
    Lets regular django models be louder!

    Regular field:
    >>> blogpost.title
    'hello world'

    Same field, but louder.
    >>> blogpost.html.title
    '<strong>HELLO WORLD!</strong>'
    """

    @property
    def html(self):
        return self._HTML(self)

    class _HTML(object):

        def __init__(self, parent):
            self.parent = parent

        def __getattr__(self, attr, *args):
            raw_text = getattr(self.parent, attr, *args)
            assert isinstance(raw_text, str), 'only words can be loud.'
            return mark_safe(self._shout(raw_text))

        def _shout(self, raw, tag='strong'):
            """ Do something useful with the text here. """
            return '<{tag}>{text}!</{tag}>'.format(
                tag=tag, text=raw.upper()
            )


class Blogpost(models.Model, LoudModelMixin):
    title = models.CharField(max_length=50)
    body = models.TextField()

      

+1


source







All Articles