# -*- coding: UTF-8 -*- import six from django.db import models from django.db.models.signals import post_init from image.forms import ImageCenterFormField from image.video_field import VideoField class ImageCenter(object): def __init__(self, image_field, x=None, y=None, xy=None): self.image_field = image_field if (not x is None and y is None) or (x is None and not y is None): raise ValueError( u"If x or y are provided, both have to be provided: x=" + six.text_type(x) + u", y=" + six.text_type(y)) if not x is None and not y is None: if x < 0 or x > 1 or y < 0 or y > 1: raise ValueError( u"Valid values for x and y go from 0 to 1: x=" + six.text_type(x) + u", y=" + six.text_type(y)) self.x = float(x) self.y = float(y) else: if xy is None: self.x = .5 self.y = .5 else: try: x, y = xy.split(",") except ValueError: x = .5 y = .5 self.x = float(x) self.y = float(y) def __str__(self): return str(self.x) + "," + str(self.y) __unicode__ = __str__ class ImageCenterField(models.Field): attr_class = ImageCenter description = "A field that stores the center of attention for an image." # __metaclass__ = models.SubfieldBase def __init__(self, image_field=None, *args, **kwargs): if image_field is not None: if not isinstance(image_field, models.ImageField) and not isinstance(image_field, VideoField): raise ValueError("image_field value must be an ImageField or VideoField instance") kwargs["default"] = ".5,.5" self.image_field = image_field super(ImageCenterField, self).__init__(*args, **kwargs) def set_instance(self, instance): self.instance = instance def formfield(self, **kwargs): defaults = {'form_class': ImageCenterFormField} defaults.update(kwargs) return super(ImageCenterField, self).formfield(**defaults) def db_type(self, connection): return "char(100)" # Esta función es llamada al leer un valor de la base de datos def to_python(self, value): if isinstance(value, ImageCenter): return value return ImageCenter(self.image_field, xy=value) # Esta función es llamada al escribir un valor en la base de datos def get_db_prep_value(self, value, connection=None, prepared=False): try: return str(value.x) + "," + str(value.y) except AttributeError: return str(value) def from_db_value(self, value, expression, connection, context=None): return ImageCenter(self.image_field, xy=value) def value_to_string(self, obj): value = getattr(obj, self.attname) return self.get_db_prep_value(value) def query_string(self): return "center=" + str(self.x) + "," + str(self.y) def post_init_capture(sender, instance, *args, **kwargs): fields = instance.__class__._meta.get_fields() for field in fields: if isinstance(field, ImageCenterField) and field.image_field: image_field = instance.__class__._meta.get_field(field.image_field.name) image_instance = instance.__getattribute__(image_field.name) image_center_instance = instance.__getattribute__(field.name) image_instance.__image_center_instance__ = image_center_instance if isinstance(image_center_instance, six.string_types): image_center_instance = ImageCenter(image_field, xy=image_center_instance) setattr(instance, field.name, image_center_instance) image_center_instance.image_path = six.text_type(image_instance) post_init.connect(post_init_capture) try: from south.modelsinspector import add_introspection_rules add_introspection_rules([], [r"^image\.fields\.ImageCenterField$"]) add_introspection_rules([], [r"^image\.video_field\.VideoField$"]) except ImportError: pass