On Tue, Nov 20, 2012 at 6:28 AM, Chris Cogdon <[email protected]> wrote:

> Hi folks!
>
> I'm creating an application to manage an art show (with art pieces to view
> and sell, silent and voice auctions, and a sales process). To have this
> work, it of course needs to keep track of people (including names,
> addresses, email, etc). But to make this more useful to anyone, I want to
> include the ability to replace the included "Person" model with another,
> should the implementor so choose.
>
> What I've done so far is to split the Person model into another app
> (called Peeps) and removed all but a few necessary linkages between the
> Artshow and Peeps app. It was reasonably simple, but a few things seem
> "dirty" so I'm wondering if anyone else has a more experienced or
> authoritative suggestion for this.
>

Ok… so… In Django 1.5, yes there is… unofficially.

Now - I must stress -- everything I'm about to say is 100% undocumented,
and 100% experimental. If it breaks, you get to keep all the shiny pieces
:-) I'm only mentioning it because I (personally) need people to experiment
in this space in order to prove to the core team that the feature is safe
for public consumption.

With that caveat in place:

In Django 1.5 (i.e., the current development branch), we've added the
ability to add swappable User models. This means you can replace Django's
builtin User model with any User model you want -- for example, a user
model that uses 'email' as the unique identifier, or one that captures API
credentials rather than first and last name.

The dirty secret is that when I implemented this feature for contrib.auth,
I did so in a way that was completely independent of the User model itself.
There aren't any explicit references to contrib.auth in the main model code
that makes swappable User models possible. In theory *any* model can be
declared as swappable, which will allow the end user to define that in
their project the "X" model will be performed by model "Y", and any foreign
keys will be re-routed appropriately.

The magic sauce: On the model you want to be swappable (Person, in your
case), add a Meta declaration:

class Person(Model):
    class Meta:
        swappable = 'CUSTOM_PERSON_MODEL'

When you synchronise your database, sycndb will look for a setting called
'CUSTOM_PERSON_MODEL'; if it exists, it won't sync Person into the
database, and will replace any references to Person with references to the
model defined in CUSTOM_PERSON_MODEL.

See the development docs for custom user models to see how this works in
practice, and adapt for your purposes. I'm intentionally going to leave the
rest vague. Call it an entrance exam -- if you can't work out what's going
on from what I've given you here and reading Django's source code, you
probably shouldn't be playing around with this sort of experimental
feature. However, I'm happy to answer specific questions if you get stuck
deep in the grass.

Once again, I must stress that this is unofficial, and you'll be in
experimental territory if you do this. The reason this is unofficial is
because some on the core team are concerned about reopening old wounds --
essentially, swapping models can lead to all sorts of headaches, and the
Django project has had these headaches in the past. Consider, for example,
if a user changes the CUSTOM_PERSON_MODEL after they've synchronised.
Hilarity *will* ensue. There's also problems related to forms and setting
an implied contract around your swappable model.

However, it *can* work; and to my mind, we're all consenting adults, so as
long as we all understand the potential pitfalls, this is the sort of thing
that may be useful.

If I haven't scared you off by this point, I certainly hope you'll have a
tinker and see if this might be palatable for your project.

Yours,
Russ Magee %-)

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

Reply via email to