# Path: textplusstuff/fields.py
# class TextPlusStuffField(TextField):
#     description = _("Text Plus Stuff Field")
# 
#     def __init__(self, *args, **kwargs):
#         self.constructed_field = kwargs.pop('constructed_field', None)
# 
#         super(TextPlusStuffField, self).__init__(*args, **kwargs)
# 
#     def get_prep_value(self, value):
#         if not isinstance(value, TextPlusStuff):
#             value = TextPlusStuff(value)
#         return value.raw_text
# 
#     def value_to_string(self, obj):
#         """
#         Prepare this field for serialization.
#         """
#         value = self.value_from_object(obj)
#         return self.get_prep_value(value)
# 
#     def from_db_value(self, value, expression, connection, context):
#         if isinstance(value, TextPlusStuff):
#             textplusstuff_instance = value
#             textplusstuff_instance.field = self.attname
#         else:
#             textplusstuff_instance = TextPlusStuff(
#                 raw_text=value, field=self.attname
#             )
# 
#         return textplusstuff_instance
# 
#     def to_python(self, value):
#         """
#         Take Markdown-flavored (and TextPlusStuffToken-laden text) and
#         returns it as a TextPlusStuff instance.
#         """
#         if isinstance(value, TextPlusStuff):
#             textplusstuff_instance = value
#             textplusstuff_instance.field = self.attname
#         else:
#             textplusstuff_instance = TextPlusStuff(
#                 raw_text=value, field=self.attname
#             )
# 
#         if value is None:
#             textplusstuff_instance = TextPlusStuff(
#                 raw_text="", field=self.attname
#             )
# 
#         return textplusstuff_instance
# 
#     def formfield(self, **kwargs):
#         formfield = super(TextPlusStuffField, self).formfield(**kwargs)
#         attrs = formfield.widget.attrs
#         attrs.update({'class': 'vLargeTextField textplusstuff'})
#         formfield.widget = TextPlusStuffWidget(
#             attrs=attrs
#         )
#         return formfield
# 
#     def update_constructed_field(self, model_instance):
#         """
#         Update field's constructed field, if defined.
# 
#         This method is hooked up this field's pre_save method to update
#         the constructed immediately before the model instance (`instance`)
#         it is associated with is saved.
#         """
#         # Nothing to update if the field doesn't have have a constructed field
#         if self.constructed_field:
#             tps_field_value = getattr(model_instance, self.attname)
#             if not isinstance(tps_field_value, TextPlusStuff):
#                 tps_field_value = self.to_python(tps_field_value)
# 
#             constructed_value = TextPlusStuffFieldSerializer(
#             ).to_representation(
#                 tps_field_value
#             )
#             setattr(
#                 model_instance,
#                 self.constructed_field,
#                 constructed_value
#             )
# 
#     def pre_save(self, model_instance, add):
#         """Return the field's value just before saving."""
#         value = super(TextPlusStuffField, self).pre_save(model_instance, add)
#         if not isinstance(value, TextPlusStuff):
#             value = TextPlusStuff(value)
#         self.update_constructed_field(model_instance)
#         return value
# 
# class TextPlusStuffConstructedField(JSONField):
#     description = _("Constructed Text Plus Stuff Field")
# 
#     def __init__(self, *args, **kwargs):
#         load_kwargs = kwargs.pop('load_kwargs', {})
#         if 'object_pairs_hook' not in load_kwargs:
#             load_kwargs.update({'object_pairs_hook': OrderedDict})
#         kwargs['load_kwargs'] = load_kwargs
#         default = kwargs.get('default', {})
#         kwargs['default'] = default
#         kwargs['editable'] = False
#         super(TextPlusStuffConstructedField, self).__init__(*args, **kwargs)


from django.db import models
from django.utils.translation import ugettext_lazy as _
from textplusstuff.fields import (
    TextPlusStuffField,
    TextPlusStuffConstructedField
)
from __future__ import unicode_literals




class RegisteredModel(models.Model):
    """
    A simple model used to test textplusstuff.registry.StuffRegistry
    """
    title = models.CharField(
        max_length=90
    )

    class Meta:
        verbose_name = _('Registered Model')
        verbose_name_plural = _('Registered Models')

    def __unicode__(self):
        return "registeredmodel:{}".format(self.pk)


class TPSTestModel(models.Model):
    content = TextPlusStuffField(
        constructed_field='content_constructed'
    )

# Path: textplusstuff/fields.py
# class TextPlusStuffField(TextField):
#     description = _("Text Plus Stuff Field")
# 
#     def __init__(self, *args, **kwargs):
#         self.constructed_field = kwargs.pop('constructed_field', None)
# 
#         super(TextPlusStuffField, self).__init__(*args, **kwargs)
# 
#     def get_prep_value(self, value):
#         if not isinstance(value, TextPlusStuff):
#             value = TextPlusStuff(value)
#         return value.raw_text
# 
#     def value_to_string(self, obj):
#         """
#         Prepare this field for serialization.
#         """
#         value = self.value_from_object(obj)
#         return self.get_prep_value(value)
# 
#     def from_db_value(self, value, expression, connection, context):
#         if isinstance(value, TextPlusStuff):
#             textplusstuff_instance = value
#             textplusstuff_instance.field = self.attname
#         else:
#             textplusstuff_instance = TextPlusStuff(
#                 raw_text=value, field=self.attname
#             )
# 
#         return textplusstuff_instance
# 
#     def to_python(self, value):
#         """
#         Take Markdown-flavored (and TextPlusStuffToken-laden text) and
#         returns it as a TextPlusStuff instance.
#         """
#         if isinstance(value, TextPlusStuff):
#             textplusstuff_instance = value
#             textplusstuff_instance.field = self.attname
#         else:
#             textplusstuff_instance = TextPlusStuff(
#                 raw_text=value, field=self.attname
#             )
# 
#         if value is None:
#             textplusstuff_instance = TextPlusStuff(
#                 raw_text="", field=self.attname
#             )
# 
#         return textplusstuff_instance
# 
#     def formfield(self, **kwargs):
#         formfield = super(TextPlusStuffField, self).formfield(**kwargs)
#         attrs = formfield.widget.attrs
#         attrs.update({'class': 'vLargeTextField textplusstuff'})
#         formfield.widget = TextPlusStuffWidget(
#             attrs=attrs
#         )
#         return formfield
# 
#     def update_constructed_field(self, model_instance):
#         """
#         Update field's constructed field, if defined.
# 
#         This method is hooked up this field's pre_save method to update
#         the constructed immediately before the model instance (`instance`)
#         it is associated with is saved.
#         """
#         # Nothing to update if the field doesn't have have a constructed field
#         if self.constructed_field:
#             tps_field_value = getattr(model_instance, self.attname)
#             if not isinstance(tps_field_value, TextPlusStuff):
#                 tps_field_value = self.to_python(tps_field_value)
# 
#             constructed_value = TextPlusStuffFieldSerializer(
#             ).to_representation(
#                 tps_field_value
#             )
#             setattr(
#                 model_instance,
#                 self.constructed_field,
#                 constructed_value
#             )
# 
#     def pre_save(self, model_instance, add):
#         """Return the field's value just before saving."""
#         value = super(TextPlusStuffField, self).pre_save(model_instance, add)
#         if not isinstance(value, TextPlusStuff):
#             value = TextPlusStuff(value)
#         self.update_constructed_field(model_instance)
#         return value
# 
# class TextPlusStuffConstructedField(JSONField):
#     description = _("Constructed Text Plus Stuff Field")
# 
#     def __init__(self, *args, **kwargs):
#         load_kwargs = kwargs.pop('load_kwargs', {})
#         if 'object_pairs_hook' not in load_kwargs:
#             load_kwargs.update({'object_pairs_hook': OrderedDict})
#         kwargs['load_kwargs'] = load_kwargs
#         default = kwargs.get('default', {})
#         kwargs['default'] = default
#         kwargs['editable'] = False
#         super(TextPlusStuffConstructedField, self).__init__(*args, **kwargs)


# Path: tests/models.py
from django.db import models
from django.utils.translation import ugettext_lazy as _
from textplusstuff.fields import (
    TextPlusStuffField,
    TextPlusStuffConstructedField
)

from __future__ import unicode_literals




class RegisteredModel(models.Model):
    """
    A simple model used to test textplusstuff.registry.StuffRegistry
    """
    title = models.CharField(
        max_length=90
    )

    class Meta:
        verbose_name = _('Registered Model')
        verbose_name_plural = _('Registered Models')

    def __unicode__(self):
        return "registeredmodel:{}".format(self.pk)


class TPSTestModel(models.Model):
    content = TextPlusStuffField(
        constructed_field='content_constructed'
    )

    content_constructed = TextPlusStuffConstructedField()