Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Conflict trying to save models when roles metaclass is applied.
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  8 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Ben Scherrey  
View profile  
 More options Nov 23 2010, 7:08 am
From: Ben Scherrey <proteus...@gmail.com>
Date: Tue, 23 Nov 2010 04:08:53 -0800 (PST)
Local: Tues, Nov 23 2010 7:08 am
Subject: Conflict trying to save models when roles metaclass is applied.
    We are attempting to apply the concepts of Domain-Context
Interaction (DCI) to our python/django development. Unfortunately, the
metaclass mechanism which the main python library supporting this uses
conflicts with that of Django's metaclass for db.models. What happens
is that a metaclass and new methods are temporarily injected into the
model object while it acts as a role within a context. While it is an
instance of that role, we cannot use the save method on it. When the
role is removed the object may then be saved. Unfortunately that's
quite unsatisfactory and I'm wondering if Django's models can be a
little smarter when figuring out whether an object is a Django
db.model instance or not (we use multiple inheritance to retain the
db.model metaclass). Alternatively, can someone who gets more about
how the metaclass stuff is working with Django suggest a fix in the
roles module that would make it get along better with Django's ORM?

    roles can be found: http://pypi.python.org/pypi/roles/0.8
    the dci group (object composition) is: http://groups.google.com/group/object-composition

    some example code showing how to make it all "work" with django
is: http://groups.google.com/group/object-composition/browse_thread/threa...

    DCI is a very exciting architecture to me that extends the object
model &MVC/T to a more logical end and addresses a lot of complex
issues in design. The concepts have significantly altered my approach
to designing new systems. I really want to be able to make this work
cleanly with Django if at all possible. Appreciate any insights.

  -- Ben Scherrey


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
bruno desthuilliers  
View profile  
 More options Nov 23 2010, 9:38 am
From: bruno desthuilliers <bruno.desthuilli...@gmail.com>
Date: Tue, 23 Nov 2010 06:38:01 -0800 (PST)
Local: Tues, Nov 23 2010 9:38 am
Subject: Re: Conflict trying to save models when roles metaclass is applied.
On 23 nov, 13:08, Ben Scherrey <proteus...@gmail.com> wrote:

Hi Ben.

Could you post the full error message AND traceback you get when
trying to save your "roled" model instance please ? Django models have
a '._meta' attribute which stores, well, metadata about the model,
like fields, tablename etc, so the author's assumption (exposed in the
thread on the 'object-composition' group) that the problem is caused
by a class name change doesn't stand. I currently lack time to dig
into this DCI thing and python-roles implementation but given enough
context (=>traceback...) I might provide some hints.

HTH


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
juacompe  
View profile  
 More options Dec 2 2010, 12:03 am
From: juacompe <juaco...@gmail.com>
Date: Wed, 1 Dec 2010 21:03:50 -0800 (PST)
Local: Thurs, Dec 2 2010 12:03 am
Subject: Re: Conflict trying to save models when roles metaclass is applied.
Hi Bruno,

I have tried to save the roled model and got [AttributeError: 'Person
+Carpenter' object has no attribute 'person_ptr_id'] as in traceback
below.

In [1]: from carpenter.models import Person, Carpenter
In [2]: jack = Person(name='Jack')
In [3]: Carpenter(jack)
Out[3]: <Person+Carpenter: Person+Carpenter object>
In [4]: jack.chop()
Out[4]: 'chop, chop'
In [5]: jack.save()
parent = <class 'carpenter.models.Person'>, field =
<django.db.models.fields.related.OneToOneField object at 0x21a4a50>
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call
last)

/home/juacompe/projects/dci/trunk/<ipython console> in <module>()

/home/juacompe/.virtualenvs/dci/lib/python2.6/site-packages/
Django-1.2.3-py2.6.egg/django/db/models/base.pyc in save(self,
force_insert, force_update, using)
    432         if force_insert and force_update:
    433             raise ValueError("Cannot force both insert and
updating in model saving.")
--> 434         self.save_base(using=using, force_insert=force_insert,
force_update=force_update)
    435
    436     save.alters_data = True

/home/juacompe/.virtualenvs/dci/lib/python2.6/site-packages/
Django-1.2.3-py2.6.egg/django/db/models/base.pyc in save_base(self,
raw, cls, origin, force_insert, force_update, using)
    474                 # this field). If so, fill it.

    475                 print 'parent = %s, field = %s' % (parent,
field)
--> 476                 if field and getattr(self,
parent._meta.pk.attname) is None and getattr(self, field.attname) is
not None:
    477                     setattr(self, parent._meta.pk.attname,
getattr(self, field.attname))
    478

AttributeError: 'Person+Carpenter' object has no attribute
'person_ptr_id'

The source code of the Person model and the Carpenter role can be
found in the link Ben gave above (http://www.google.com/url?
sa=D&q=http://groups.google.com/group/object-composition/browse_thread/
thread/fbb11a1e02b68de9&usg=AFQjCNFHv1njxL4B0SksOgPRFvj_hqhC0Q)

Any comments or suggestions would be really appreciated.

Thank you and best regards,
Chokchai Phatharamalai.

On Nov 23, 9:38 pm, bruno desthuilliers


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
bruno desthuilliers  
View profile  
 More options Dec 2 2010, 12:00 pm
From: bruno desthuilliers <bruno.desthuilli...@gmail.com>
Date: Thu, 2 Dec 2010 09:00:12 -0800 (PST)
Local: Thurs, Dec 2 2010 12:00 pm
Subject: Re: Conflict trying to save models when roles metaclass is applied.
On 2 déc, 06:03, juacompe <juaco...@gmail.com> wrote:

> Hi Bruno,

> I have tried to save the roled model and got [AttributeError: 'Person
> +Carpenter' object has no attribute 'person_ptr_id'] as in traceback
> below.

Uhu... Very quick anwser, would need more in-depth analyses, but I'm
pretty confident the root of the problem is here: roles uses
inheritance to build the new "Person+Carpenter" class, but then for
Django's ModelBase this kind of triggers the multi-table inheritance
behaviour (http://docs.djangoproject.com/en/1.2/topics/db/models/
#multi-table-inheritance).

Since - AFAICT - roles are about behaviour, using proxy inheritance
(http://docs.djangoproject.com/en/1.2/topics/db/models/#proxy-models)
could possibly cure the problem. Just add an inner "Meta" class in
your role model with "proxy = True" as class attribute (cf the above
link) and see if it works better.

My 2 cents.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
juacompe  
View profile  
 More options Dec 3 2010, 2:00 am
From: juacompe <juaco...@gmail.com>
Date: Thu, 2 Dec 2010 23:00:34 -0800 (PST)
Local: Fri, Dec 3 2010 2:00 am
Subject: Re: Conflict trying to save models when roles metaclass is applied.
Hi Bruno,

Thank you very much!! Adding an inner Meta class works like charm.
Below is the working code with proving testcases
--------------------------
models.py
--------------------------
from django.db.models import Model, CharField
from django.db.models.base import ModelBase

from roles import RoleType

class ModelBaseRoleType(ModelBase, RoleType):
    """
    As every Django model which inherits from django.db.models.Model
already has
    ModelBase as its __metaclass__, applying a RoleType to it would
causes a
    conflict because a Python class can apply only 1 metaclass.

    In order to resolve the conflict, a new type named
ModelBaseRoleType is
    created.

    ModelBaseRoleType inherits from Django's ModelBase and Roles'
RoleType.

    ModelBaseRoleType also needs an inner Meta class to tell Django
that
    this will be a proxy class; otherwise, an AttributeError will be
raised
    when a *roled* model try to call save(). -- Thanks to Bruno
Desthuilliers
    for pointing this out. :)
    """
    # this metaclass avoids AttributeError in Django model
    class Meta:
        proxy = True

class Person(Model):
    name = CharField(max_length=20)

class Carpenter(object):
    __metaclass__ = ModelBaseRoleType

    def chop(self):
        return 'chop, chop'

-----------------
tests.py
-----------------
from carpenter.models import Person, Carpenter
from roles import RoleType, clone

from django.test import TestCase
from django.db import DatabaseError

class TestCarpenter(TestCase):
    def test_assign_role(self):
        """
        Role Carpenter is being assigned to a person
        """
        p = Person('juacompe')
        Carpenter(p)

    def test_save(self):
        jack = Person()
        jack.name = 'Jack'
        # applying carpenter role
        Carpenter(jack)
        self.failUnless(isinstance(jack, Person))
        self.failUnless(isinstance(jack, Carpenter))
        # a carpenter can chop
        jack.chop()
        # a person has name
        jack.name = 'Jack the giant killer'
        # django model can save
        jack.save()

Thank you very much!!

Best regards,
Chokchai P.

On Dec 3, 12:00 am, bruno desthuilliers


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
bruno desthuilliers  
View profile  
 More options Dec 3 2010, 12:19 pm
From: bruno desthuilliers <bruno.desthuilli...@gmail.com>
Date: Fri, 3 Dec 2010 09:19:29 -0800 (PST)
Local: Fri, Dec 3 2010 12:19 pm
Subject: Re: Conflict trying to save models when roles metaclass is applied.

On 3 déc, 08:00, juacompe <juaco...@gmail.com> wrote:

> Hi Bruno,

> Thank you very much!! Adding an inner Meta class works like charm.

Cool 8)

Now beware, there _might_ be a couple other dark corners... I strongly
suggest you take a look at ModelBase implementation and possibly
extend your test cases, at least to make sure you spotted all possible
side-effects of the role+model combo.


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
juacompe  
View profile  
 More options Dec 4 2010, 5:37 am
From: juacompe <juaco...@gmail.com>
Date: Sat, 4 Dec 2010 02:37:56 -0800 (PST)
Local: Sat, Dec 4 2010 5:37 am
Subject: Re: Conflict trying to save models when roles metaclass is applied.
Good idea! I'll try that and update the post.

I'll be out of town for a week, don't think i can code during that. so
my next post would be around the next weekend.

Have a good day!
Chokchai P.

On Dec 4, 12:19 am, bruno desthuilliers


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
juacompe  
View profile  
 More options Dec 12 2010, 8:18 am
From: juacompe <juaco...@gmail.com>
Date: Sun, 12 Dec 2010 05:18:01 -0800 (PST)
Local: Sun, Dec 12 2010 8:18 am
Subject: Re: Conflict trying to save models when roles metaclass is applied.
I did not have time to go over the implementation of ModelBase class
yet but I tried extend my test cases and want to update the progress.

I apply the Carpenter role (in the earlier post) in setUp of all test
classes in 2 small projects and add the test below in each of them.

-------------------
    def test_carpenter_role_applied(self):
        s = self.student
        self.failUnless(isinstance(s, Student))
        self.failUnless(isinstance(s, Carpenter))
        s.chop()
--------------------

Just to test that the model are properly roled and ran the whole test
suite to see if any of my assumptions were broken. All pass! Quite
happy with the result. :)

Thank again to Bruno for his kind advice. ;)

Best regards,
Chokchai P.

On Dec 4, 5:37 pm, juacompe <juaco...@gmail.com> wrote:


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »