Re: Django Model Inheritance

2007-12-31 Thread Sridhar Ratnakumar



On Dec 30 2007, 12:47 am, "Waylan Limberg" <[EMAIL PROTECTED]> wrote:
> On Dec 29, 2007 8:49 AM, Sridhar Ratnakumar <[EMAIL PROTECTED]> wrote:
>
> > [that link is going down -- hence, I'm pasting the contents below]
>
> Your willingness to share is much apprciated. However, things tend to
> become quickly forgoten and lost in the list. Not that we do so on
> pupose; that's just the nature of the beast. If you are providing a
> patch, I'd suggest opening a ticket [1]. If you are simply providing a
> snippet to help other users solve a problem, I'd suggest posting it to
> djangosnippets.org [2]. For something more involved than a simple
> snippet, perhaps adding a page to the appropriate section of the wiki
> [3] would be more helpful.

I added a snippet - http://www.djangosnippets.org/snippets/529/


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Django Model Inheritance

2007-12-29 Thread Waylan Limberg

On Dec 29, 2007 8:49 AM, Sridhar Ratnakumar <[EMAIL PROTECTED]> wrote:
>
> [that link is going down -- hence, I'm pasting the contents below]
>

Your willingness to share is much apprciated. However, things tend to
become quickly forgoten and lost in the list. Not that we do so on
pupose; that's just the nature of the beast. If you are providing a
patch, I'd suggest opening a ticket [1]. If you are simply providing a
snippet to help other users solve a problem, I'd suggest posting it to
djangosnippets.org [2]. For something more involved than a simple
snippet, perhaps adding a page to the appropriate section of the wiki
[3] would be more helpful.

[1]: http://code.djangoproject.com/simpleticket
[2]: http://www.djangosnippets.org
[3]:http://code.djangoproject.com/wiki/DjangoResources


-- 

Waylan Limberg
[EMAIL PROTECTED]

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Django Model Inheritance

2007-12-29 Thread Sridhar Ratnakumar

[that link is going down -- hence, I'm pasting the contents below]

Django ORM does not support inheritance. Inheritance is a good thing.
Often I want some of the database models to share some common fields
and the same manager. For example consider the case of adding the
delete proxy.

class RetainDeletesMixin(object):

class NonDeleted(models.Manager):

def get_query_set(self):
return super(NonDeleted, self).get_query_set().filter(
delete_flag=0)

delete_flag = models.IntegerField(null=True, blank=True,
default=0)

objects = NonDeleted()

def delete(self):
self.delete_flag = 1
self.save()


class Item(RetainDeletesMixin, models.Model):
...

Here we are extending the model Item by adding a mixin that overrides
the delete method - so that when we do item.delete() the model is not
actually deleted but merely flagged (delete_flag=1) so. This means the
get_query_set method should also be told not to return the flagged
models. In Python speak,

>>> items = Item.objects.all()
>>> item = items[0]
>>> len(items)
1
>>> item.delete_flag
0
>>> item.delete()
>>> item.delete_flag
1
>>> len(Item.objects.all())
0
>>>

But this will not work. Django does not consider delete_flag, which is
inherited from RetainDeletesMixin, as a database column at all. So I
came up with the following metaclass hack which enables you to design
the django models based on the inheritance pattern like the above,

class RetainDeletesMixin(object):

class NonDeleted(models.Manager):

def get_query_set(self):
# Ideally, we should be using `super` here but we don't
because
# the variable `NonDeleted` will not be accessible once we
# 'copy' this class in the metaclass.
return models.Manager.get_query_set(self).filter(
delete_flag=0)

delete_flag = models.IntegerField(null=True, blank=True,
default=0)

objects = NonDeleted()

def delete(self):
self.delete_flag = 1
self.save()

def django_extends(base):

class ProxyMetaClass(models.Model.__metaclass__):

def __new__(cls, name, bases, attrs):
# The following attributes must be moved *prior* to
deferring
# execution to the models.Model's metaclass, because they
# will be manipulated by __new__
#  - models.fields.Field instances
#  - objects (ModelManager)
for key in dir(base):
if not key.startswith('_'):
obj = getattr(base, key)
if isinstance(obj, models.fields.Field) or \
key == 'objects':
attrs[key] = obj
delattr(base, key)
# Delete objects that have attribute
'contribute_to_class'
# for otherwise that will break in
# base.py:Model.add_to_class
# Eg: inner classes inherited from models.Manager
elif hasattr(obj, 'contribute_to_class'):
delattr(base, key)

return super(ProxyMetaClass,
 cls).__new__(cls, name,
  tuple([base]+list(bases)),
  attrs)

frame = sys._getframe(1)
frame.f_locals['__metaclass__'] = ProxyMetaClass

class Item(models.Model):
django_extends(RetainDeletesMixin)
...

What this basically does is - copy the database fields and objects
from the base class (RetainDeletesMixin) to the derived class (Item)
so that Django will recognize it upon processing in ModelBase. It also
makes RetainDeletesMixin a base class of Item. I have not tested this
code extensively, but it works for the models that I have written in
our application.


On Dec 19, 1:53 pm, Sridhar Ratnakumar <[EMAIL PROTECTED]>
wrote:
> I wanted to share this little hack of mine - conceptual (not database-
> based)inheritancefordjango:http://nearfar.org/blog/django-model-inheritance.html
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---



Re: Django Model Inheritance

2007-12-19 Thread ivan.illarionov

1. You still can use super in NonDeleted.get_query_set by using
self.__class__ instead of NonDeleted
2. It could be better to use issubclass(key, models.Manager) instead
of key == 'objects'

On 19 дек, 11:53, Sridhar Ratnakumar <[EMAIL PROTECTED]> wrote:
> I wanted to share this little hack of mine - conceptual (not database-
> based) inheritance for 
> django:http://nearfar.org/blog/django-model-inheritance.html
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~--~~~~--~~--~--~---