Switched Attribute ManyToManyValues to have a ManyToManyField to ForeignKeyValues...
[philo.git] / models / base.py
index 0c2c975..0077250 100644 (file)
@@ -46,7 +46,12 @@ def unregister_value_model(model):
 
 
 class AttributeValue(models.Model):
-       attribute = generic.GenericRelation('Attribute', content_type_field='value_content_type', object_id_field='value_object_id')
+       attribute_set = generic.GenericRelation('Attribute', content_type_field='value_content_type', object_id_field='value_object_id')
+       
+       @property
+       def attribute(self):
+               return self.attribute_set.all()[0]
+       
        def apply_data(self, data):
                raise NotImplementedError
        
@@ -81,7 +86,7 @@ class JSONValue(AttributeValue):
 
 
 class ForeignKeyValue(AttributeValue):
-       content_type = models.ForeignKey(ContentType, related_name='foreign_key_value_set', limit_choices_to=value_content_type_limiter, verbose_name='Value type', null=True, blank=True)
+       content_type = models.ForeignKey(ContentType, limit_choices_to=value_content_type_limiter, verbose_name='Value type', null=True, blank=True)
        object_id = models.PositiveIntegerField(verbose_name='Value ID', null=True, blank=True)
        value = generic.GenericForeignKey()
        
@@ -104,15 +109,14 @@ class ForeignKeyValue(AttributeValue):
 
 
 class ManyToManyValue(AttributeValue):
-       # TODO: Change object_ids to object_pks.
-       content_type = models.ForeignKey(ContentType, related_name='many_to_many_value_set', limit_choices_to=value_content_type_limiter, verbose_name='Value type', null=True, blank=True)
-       object_ids = models.CommaSeparatedIntegerField(max_length=300, verbose_name='Value IDs', null=True, blank=True)
+       content_type = models.ForeignKey(ContentType, limit_choices_to=value_content_type_limiter, verbose_name='Value type', null=True, blank=True)
+       values = models.ManyToManyField(ForeignKeyValue, blank=True, null=True)
        
        def get_object_id_list(self):
-               if not self.object_ids:
+               if not self.values.count():
                        return []
                else:
-                       return self.object_ids.split(',')
+                       return self.values.values_list('object_id', flat=True)
        
        def get_value(self):
                if self.content_type is None:
@@ -122,10 +126,22 @@ class ManyToManyValue(AttributeValue):
        
        def set_value(self, value):
                # Value is probably a queryset - but allow any iterable.
+               
+               # These lines shouldn't be necessary; however, if value is an EmptyQuerySet,
+               # the code won't work without them. Unclear why...
+               if not value:
+                       value = []
+               
                if isinstance(value, models.query.QuerySet):
                        value = value.values_list('id', flat=True)
                
-               self.object_ids = ','.join([str(v) for v in value])
+               self.values.filter(~models.Q(object_id__in=value)).delete()
+               current = self.get_object_id_list()
+               
+               for v in value:
+                       if v in current:
+                               continue
+                       self.values.create(content_type=self.content_type, object_id=v)
        
        value = property(get_value, set_value)
        
@@ -141,7 +157,7 @@ class ManyToManyValue(AttributeValue):
                else:
                        self.content_type = cleaned_data.get('content_type', None)
                        # If there is no value set in the cleaned data, clear the stored value.
-                       self.object_ids = ""
+                       self.value = []
        
        class Meta:
                app_label = 'philo'