On Sat, Jan 12, 2008 at 02:15:32PM -0500, Wanrong Lin wrote:
> I have a data model case that I think probably is quite common to other 
> people too, and I did not find a way to do it with current Django, so I 
> wonder whether the developers can take a look of it.
> 
> My situation is:
> 
> I have quite a few data model classes that share some common fields, so 
> I have the following model code:
> 
> --------------------
> class Common(models.Model):
>     # common fields
>     ......
> 
> class Model_A(Common):
>     # extra fields
>     ......
> 
> class Model_B(Common):
>     # extra fields
>     ......
> -------------------
> 
> That works, except that a database table will be created for "Common", 
> which will never be used by itself.
> 
> So I will just keep "Common" table empty, not a big deal. But, to make 
> it more elegant (which I suspect a lot of Python programmers are 
> obsessed about), can we add some kind of mechanism to tell Django that 
> "Common" is an "abstract model" that is not intended to be used by 
> itself, so no table needs to be created?

This is a dirty hack mind you, but a rather effective one- I 
personally use it for when I need to create common structures w/in 
tables and need to able to change the structure definitions in a 
single spot.  If you did the following-

def add_common_fields(local_scope):
    local_scope['field1'] = models.IntegerField(blank=True, 
       null=True)
    local_scope['field2'] = models.CharField(maxlength=255, 
       blank=True, null=True)
    # other common definitions, same thing, updating the passed in
    # dict

you could then just do

class Model_A(models.Model):
   add_common_fields(locals())
   # other fields

class Model_B(models.Model):
   add_common_fields(locals())
   # other fields.

Pros of the approach:
1) you're easily able to add common fields to model definitions, and 
 it Just Works (TM)
2) since the class scope is executed in order, via shifting around the 
 add_common_fields invocation you can shift the sql column definition 
 as needed.

Cons:
1) exploits the fact locals() in class scope is a mutable dict- I've 
 yet to see commentary indicating this will change anytime soon for 
 cpython, but I've no idea if this works in ironpython/jython (assume 
 so due to metaclass semantics, but I've not tested it).
2) if you've never seen that trick before and come across it in code, 
 it's likely going to confuse the hell out of the person examining it.  
 Comments likely warranted to combat that.
3) inheritance would be a bit more pythonic (although inheritance 
 requires some funkyness to be able to control field ordering).

You probably could fold the approach above into a metaclass if desired 
also- would be a bit more pythonic possibly.

Either way, it's a useful trick, so hopefully it helps-
~brian

Attachment: pgpaCFiNDILUl.pgp
Description: PGP signature

Reply via email to