2014-10-26 7 views
2

я продлил django-markdown с полем пользовательской модели, которая позволяет определять классы:Пользовательские модели поле рендеринг в шаблоне Django

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

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

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

Теперь, когда дело доходит до предоставления этих полей в шаблоне это можно сделать :

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

Однако, это, кажется, чтобы победить объект создания пользовательских полей модели в первую очередь (для повышения Сухость), и предпочтительно следует избегать любой ценой.

Итак, есть ли способ сделать только {{ model.text }} {{ model2.description }} без загрузки тегов шаблона и без фильтрации, как-то определяя метод render в настраиваемом поле?

Аналогичный вопрос уже задан: Is there a way to customize how the value for a custom Model Field is displayed in a template?, но ответ влечет за собой добавление метода к модели. Это означало бы добавление методов к MyModel и MySecondModel, а также любые последующие. Опять же, это побеждает весь объект СУХОЙ!

NB Оба класса моделей являются подклассами чего-то другого, поэтому определение микса возможно, но, безусловно, должно быть лучше!

ответ

1

Я в той же ситуации, что и вы. Я решил, что смогу его решить, используя mixin для класса Model.

Кажется, что это работает, но я не уверен, что это правильный способ сделать это. Чувствуется, как грязный хак, который я не совсем понимаю.

Вы должны, естественно, заменить метод _shout() на что-то более полезное.

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() 
Смежные вопросы