Hi,

I just spent some time looking for a way to extend the User model in a
way that would allow me to:

1. add fields to the model itself,
2. use the standard admin interface to edit them,
3. keep changes to Django minimal and generic.

I came up with something that actually works well and is generic
enough to extend any other model: I changed ModelBase.__new__ to call
a function that modifies attributes of the new class before it gets
created.  The function is defined in project settings file, so it is
easy to have different User models in different projects without
further changes to Django code.

Example from my settings.py:

> def patch_user_model(name, bases, attrs):
>     from django.db import models
>     from myproject.myapp.models import Company
>
>     attrs['phone_numbers'] = models.CharField(maxlength=300)
>     attrs['height'] = models.IntegerField(blank=True, null=True)
>     attrs['employer'] = models.ForeignKey(Company, blank=True, null=True)
>
>     # fields[1] is the 'Personal info' tuple, fields[1][1] is the contents 
> dict
>     attrs['Admin'].fields[1][1]['fields'] += ('phone_numbers', 'employer', 
> 'height')
>
>     return attrs
>
> MODEL_PATCHES = {'auth.User': patch_user_model}

It is possible to specify patches for multiple models.  You will need
to recreate model tables every time you change the patch function.

The attached file is the patch for Django.

Cheers,
-mk



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@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-users
-~----------~----~----~----~------~----~------~--~---
Index: django/db/models/base.py
===================================================================
--- django/db/models/base.py	(revision 3116)
+++ django/db/models/base.py	(working copy)
@@ -25,6 +25,14 @@
         if not bases or bases == (object,):
             return type.__new__(cls, name, bases, attrs)
 
+        # patch the class
+        if hasattr(settings, 'MODEL_PATCHES'):
+            # quietly assume it is a dict
+            model_patches = settings.MODEL_PATCHES
+            func = model_patches.get(attrs['__module__'].split('.')[-2] + '.' + name, None)
+            if func:
+                attrs = func(name, bases, attrs)
+        
         # Create the class.
         new_class = type.__new__(cls, name, bases, {'__module__': attrs.pop('__module__')})
         new_class.add_to_class('_meta', Options(attrs.pop('Meta', None)))

Reply via email to