Changes between Initial Version and Version 1 of CookBookGenericAttribute


Ignore:
Timestamp:
12/13/2006 02:38:39 PM (13 years ago)
Author:
David S. <davidschein@…>
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • CookBookGenericAttribute

    v1 v1  
     1See http://www.djangoproject.com/documentation/models/generic_relations/.
     2
     3'''Note''': As of today, 13-DEC-06, this admonishment applies:
     4{{{
     5Generic relations: a "generic foreign key" feature is currently under development,
     6but not yet completed. There is no support for it yet in the admin application, and
     7it is probably unwise to attempt to use it in a production application.
     8}}}
     9--from http://code.djangoproject.com/
     10
     11Also, I do not think that this is particularly good data modeling if you have a choice, but when migrating an application and dealing with legacy data as you go, it can be useful if it is not abused.
     12
     13== Model Source Code ==
     14{{{
     15#!python
     16class AttributeManager(models.Manager):
     17    def with_attr(self, attr_name):
     18        return Attribute.objects.filter(name=attr_name)
     19
     20    def type_with_attr(self, type_name, attr_name):
     21        return Attribute.objects.filter(content_type__name=type_name, name=attr_name)
     22
     23    def type_with_attr_value(self, type_name, attr_name, value):
     24        return Attribute.objects.filter(content_type__name=type_name, name=attr_name, value=value)
     25
     26    def obj_attr_list(self, obj):
     27        ctype = ContentType.objects.get_for_model(obj)
     28        return  Attribute.objects.filter(content_type__pk=ctype.id, object_id=obj.id)
     29
     30    def obj_attr_value(self, obj, attr_name):
     31        ctype = ContentType.objects.get_for_model(obj)
     32        try:
     33            av = Attribute.objects.get(name=attr_name, content_type__pk=ctype.id, object_id=obj.id)
     34        except Attribute.DoesNotExist:
     35            return None
     36        return av.value
     37
     38class Attribute(models.Model):
     39    name = models.CharField(maxlength=25)
     40    content_type = models.ForeignKey(ContentType)
     41    object_id = models.PositiveIntegerField()
     42    value = models.CharField(maxlength=255)
     43   
     44    content_object = models.GenericForeignKey()
     45    objects = AttributeManager()
     46
     47    class meta:
     48        unique_together = (('name', 'content_type', 'object_id'),)
     49   
     50    def __str__(self):
     51        return "%s.%s.%s=%s" % (self.content_type.name, self.content_object, self.name, self.value,)
     52}}}
     53
     54== Sample API usage ==
     55This sample code assumes you added the above models to the sample found at http://www.djangoproject.com/documentation/models/generic_relations/.
     56
     57{{{
     58#!python
     59>>> diamond = Mineral.objects.create(name="Diamond", hardness=10)
     60>>> emerald = Mineral.objects.create(name="Emerald", hardness=6)
     61>>> Attribute.objects.create(content_object=quartz, name='color', value='black')
     62<Attribute: mineral.Quartz.color=black>
     63
     64>>> Attribute.objects.create(content_object=emerald, name='color', value='green')
     65<Attribute: mineral.Emerald.color=green>
     66
     67>>> Attribute.objects.with_attr('color')
     68[<Attribute: mineral.Quartz.color=black>, <Attribute: mineral.Emerald.color=green>]
     69
     70>>> Attribute.objects.type_with_attr('mineral', 'color')
     71[<Attribute: mineral.Quartz.color=black>, <Attribute: mineral.Emerald.color=green>]
     72
     73>>> Attribute.objects.create(content_object=eggplant, name='color', value='purple')
     74<Attribute: vegetable.Eggplant.color=purple>
     75
     76>>> Attribute.objects.with_attr('color')
     77[<Attribute: mineral.Quartz.color=black>, <Attribute: mineral.Emerald.color=green>, <Attribute: vegetable.Eggplant.color=
     78purple>]
     79
     80>>> Attribute.objects.type_with_attr('mineral', 'color')
     81[<Attribute: mineral.Quartz.color=black>, <Attribute: mineral.Emerald.color=green>]
     82
     83>>> Attribute.objects.type_with_attr_value('mineral', 'color', 'green')
     84[<Attribute: mineral.Emerald.color=green>]
     85
     86>>> Attribute.objects.type_with_attr_value('mineral', 'color', 'red')
     87[]
     88
     89>>> Attribute.objects.obj_attr_list(quartz)
     90[<Attribute: mineral.Quartz.color=black>]
     91
     92>>> Attribute.objects.obj_attr_value(quartz, 'color')
     93'black'
     94}}}
Back to Top