Skip to content

Commit

Permalink
first shot at cleaning up signal code
Browse files Browse the repository at this point in the history
  • Loading branch information
jefftriplett committed Jan 30, 2010
1 parent eccffe6 commit 38a595e
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 97 deletions.
22 changes: 12 additions & 10 deletions django_proxy/models.py
Expand Up @@ -4,14 +4,16 @@
from datetime import datetime
from django_proxy.managers import PublicManager


class ProxyBase(models.Model):
'''Represents the proxy objects. Retains the name, description,
and any tags related to the associated object.
"""
Represents the proxy objects. Retains the name, description, and any tags
related to the associated object.
A good use, I've found, for this type of object is aggregate view of all
content types in an RSS feed (post, links, tweets, etc.).
'''
"""
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey()
Expand All @@ -21,19 +23,19 @@ class ProxyBase(models.Model):
description = models.TextField(blank=True, null=True)
tags = models.CharField(max_length=255, blank=True, null=True)
pub_date = models.DateTimeField(default=datetime.now)

#audit fields
created_on = models.DateTimeField(default=datetime.now)
updated_on = models.DateTimeField(default=datetime.now)

objects = PublicManager()

def __unicode__(self):
return '%s' % self.title

class Meta:
abstract = True

def save(self, *args, **kwargs):
self.updated_on = datetime.now()
super(ProxyBase, self).save(*args, **kwargs)
Expand Down
203 changes: 116 additions & 87 deletions django_proxy/signals.py
@@ -1,105 +1,134 @@
import datetime

from django.db.models import get_model
from django.contrib.contenttypes.models import ContentType


def proxy_save(sender, **kwargs):
''' Handles the save/update of a Proxy instance. '''
instance = kwargs['instance']
created = kwargs['created']
class DjangoProxy(object):
instance = None
object = None
proxy_model = None

cls = instance.ProxyMeta
model_str = getattr(cls, 'model_str', 'django_proxy.proxy')
model = get_model(*model_str.split('.'))
obj = model()
active = False
_required_fields = ['title', 'description']
_field_mappings = [
('title', None),
('description', None),
('pub_date', datetime.datetime.now()),
('tags', None),
]

if created:
obj.content_object = instance
else:
try:
ctype = ContentType.objects.get_for_model(instance)
obj = model._default_manager.get(object_id=instance.id, content_type=ctype)
except model.DoesNotExist:
obj = model()
obj.content_object = instance

if hasattr(cls, 'active'):
if isinstance(cls.active, basestring):
active_field = getattr(instance, cls.active, None)
if callable(active_field):
active = active_field()
else:
active = active_field
def __init__(self, instance, created=None):
self.instance = instance
self.proxy_model = instance.ProxyMeta

model = self._get_proxy_model(instance)
self.object = model()

if created:
self.object.content_object = instance
else:
try:
active_field = cls.active
objfield = active_field.keys()[0]
active_status = active_field.values()[0]
actual_status = getattr(instance, objfield, None)
if active_status == actual_status:
active = True
except Exception:
# deal with this better...
pass
else:
active = True

if not active and obj.id:
obj.delete()
return

if hasattr(cls, 'title'):
title = getattr(instance, cls.title, None)
if callable(title):
obj.title = title()
else:
obj.title = title
else:
raise Exception('Missing title field')

if hasattr(cls, 'description'):
description = getattr(instance, cls.description, None)
if callable(description):
obj.description = description()
else:
obj.description = description
else:
raise Exception('Missing description field')

#proxy pub_date isn't required so confirm
if hasattr(cls, 'pub_date'):
pub_date = getattr(instance, cls.pub_date, None)
if callable(pub_date):
obj.pub_date = pub_date()
ctype = ContentType.objects.get_for_model(instance)
self.object = model._default_manager.get(object_id=instance.id, content_type=ctype)
except model.DoesNotExist:
self.object = model()
self.object.content_object = instance

def _get_attr(self, attr, obj):
if hasattr(self.proxy_model, attr):
value = getattr(self.instance, getattr(obj, attr))
if callable(value):
return value()
else:
return value

def _get_proxy_model(self, instance):
model_str = getattr(instance.ProxyMeta, 'model_str', 'django_proxy.proxy')
model = get_model(*model_str.split('.'))
return model

def _valdiate(self):
missing = []
for field in self._required_fields:
if not getattr(self.proxy_model, field, None):
missing.append(field)
if len(missing):
raise ValueError('Missing required fields: %s' % (', '.join(missing)))

def create(self):
self._valdiate()
active = self.get_active()
object = self.object

if active:
for mapping in self._field_mappings:
setattr(object, mapping[0], self._get_attr(mapping[0], self.proxy_model) or mapping[1])
object.active = active
object.save()

elif object.id:
object.delete()

def delete(self):
"""
Remove any remaining child/associated Proxy records.
"""
model = self._get_proxy_model(self.instance)
ctype = ContentType.objects.get_for_model(self.instance)
try:
self.object = model._default_manager.get(object_id=self.instance.id, content_type=ctype)
self.object.delete()
except model.DoesNotExist:
pass

def get_active(self):
active = False
if hasattr(self.proxy_model, 'active'):
if isinstance(self.proxy_model.active, basestring):
active_field = getattr(self.instance, self.proxy_model.active)
if callable(active_field):
active = active_field()
else:
active = active_field

elif isinstance(self.proxy_model.active, dict):
try:
active_field = self.proxy_model.active
objfield = active_field.keys()[0]
active_status = active_field.values()[0]
actual_status = getattr(self.instance, objfield)
if active_status == actual_status:
active = True

except Exception:
pass
else:
obj.pub_date = pub_date
active = True

#proxy tag isn't require so confirm
if hasattr(cls, 'tags'):
tags = getattr(instance, cls.tags, None)
if callable(tags):
obj.tags = tags()
else:
obj.tags = tags
return active

if active:
obj.save()

def proxy_save(sender, **kwargs):
"""
Handles the save/update of a Proxy instance.
"""
instance = kwargs['instance']
created = kwargs['created']

dp = DjangoProxy(instance, created)
dp.create()


def proxy_delete(sender, **kwargs):
'''Responsible for handling the deletion of any child/associated Proxy records.
"""
Responsible for handling the deletion of any child/associated Proxy records.
Coupled to associated object's post_delete signal.
'''
"""
instance = kwargs['instance']
ctype = ContentType.objects.get_for_model(instance)

cls = instance.ProxyMeta
model_str = getattr(cls, 'model_str', 'django_proxy.proxy')
model = get_model(*model_str.split('.'))
try:
obj = model._default_manager.get(object_id=instance.id, content_type=ctype)
obj.delete()
except model.DoesNotExist:
pass

dp = DjangoProxy(instance)
dp.delete()

0 comments on commit 38a595e

Please sign in to comment.