Hi all,

I've seen some level of interest in the idea of a lazy foreign key
(one whose target table is determined by project configuration in some
way, not hardcoded by the app/model in which it lives). The idea was
most recently brought up again in Eric Florenzano's keynote at
DjangoCon. I have some ideas regarding possible API for this, and
would be glad for feedback.

First, a couple motivating use cases:

1. Reusable apps overuse GenericForeignKey. GFKs are inefficient and
smell bad. They're good to have around when you really need to link to
any one of a possibly-growing set of models. But currently reusable
apps often use them anytime they want to link to "some domain model
but we don't know which one" - even if in practice in most cases it
will be only one! A lazy foreign key would be a better solution.

2. Standardization with flexibility: i.e. possible-future replacement
of contrib.auth.User. To be clear, I am not at this point proposing
any changes at all to contrib.auth. But in some future possible
contrib.auth refactoring, a lazy foreign key could provide a way for
reusable apps to point to a common User model, without Django having
to provide a concrete implementation of that model.

The concept:

We introduce the "virtual" model, which is an abstract model with the
following additional characteristics:

- It can be the target of a ForeignKey.
- It may only have one direct concrete subclass, and if it is the
target of any ForeignKey it must have exactly one.

At runtime, any ForeignKeys pointing to a virtual model are resolved
to actually point to the concrete subclass of that virtual model.

Like an abstract model, a virtual model may include fields, methods,
etc. These can be considered the specification of an interface: any
model with a ForeignKey to this virtual model can expect the concrete
model to satisfy that interface. This is particularly helpful for a
contrib.auth-type use case: reusable apps don't only need a User model
to point FKs at, they also often need at least some minimal set of
fields/properties they can rely on being present.

It's not required for the virtual model to have any fields, of course:
in some use cases (voting, tagging) the reusable app doesn't need to
know anything at all about its target model. A hypothetical voting app
could simply provide an empty "VotableObject" virtual model, which
would be inherited by the domain model which can receive votes. Since
Django already supports multiple inheritance for abstract models, this
is a minimal and non-restrictive requirement for the domain model
author.

Advantages of this proposal:

1. No new settings.
2. In terms of new code API, almost nothing: a new "virtual = True"
Meta keyword.
3. Very little conceptual overhead; reuses existing constructs as much
as possible.

I plan to put together a patch to show working code for this, but I'd
be glad for any feedback at this point, especially if there are
obvious conceptual problems I'm overlooking. Thanks!

Carl

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

Reply via email to