Related to this is that I'd say it would be favorable if reversed
relationships could be edited through the admin page by default.
While I can see the reason why this is appealing from a data modeling
perspective, a quick look at the underlying mechanics quickly reveals
the reason why this hasn't been implemented.
If a model A has a foreign key on model B, then the table for A
requires a field to track the relation. However, if model B has a
"many to one" on A.... table A requires a field.
This makes the process of rolling out new models could lead to some
surprising situations. For example, with the current suite of relation
fields, you can always add a new model, run syncdb, and know that your
tables will be correct. However, this won't be the case if you allow
ManyToOne fields - you need to have the additional constraint that the
model to which you are linking hasn't been created yet.
In short, something that is a relatively simple from a data modeling
perspective has the potential to open all sorts of SQL management
problems.
Of course, this sort of thing would be much easier to handle if there
was a baked in schema evolution framework - but we don't have one of
those.... yet :-)
> Related to this is that I'd say it would be favorable if reversed
> relationships could be edited through the admin page by default.
This is a separate issue, but one that is more likely to get support -
although the real fix is to correct the underlying forms handling to
allow for the reverse relationships, not to fix admin specifically.
Yours,
Russ Magee %-)
--
----
\X/ /-\ `/ |_ /-\ |\|
Waylan Limberg
You are absolutely correct that the databases would be identical.
However, this misses my point.
The critical difference is that under option 1, all the information
required to create the table for 'parent'. is contained on the Parent
model, and all the information required to create the table for
'child' is contained on the Child model. This means that as long as
you are able to import the model (i.e. there are no FK references to
models that haven't been defined), you can synchronize each model and
know that you have all the information that you require in order to
complete the synchronization accurately.
Under option 2, some of the information required for the child table
is contained on the Parent model. Therefore, you can't know for
certain if synchronization will be completed, because correctly
synchronizing Parent requires that the child either (a) hasn't been
synchronized, or (b) can be modified to add the new required column.
Why does this matter? This is entirely an issue of the complexity of
the synchronization process. Consider one of the most likely use
cases: writing a pluggable Django application that tracks the home
address of a contrib.auth.User.
I start with my project, and I add contrib.auth to INSTALLED_APPS. I
synchronize the database and set up admin, media etc.
Now, I want to add my pluggable "postal" application. This postal app
contains Address model:
class Address(Model):
street = CharField()
city = CharField()
zipcode = CharField()
users = ManyToOne(User)
However, I wouldn't be able to easily add my "postal" pluggable
application to INSTALLED_APPS. The auth.User table already exists, so
it isn't a simple task to add the extra 'address_id' column that the
Address model requires.
Resolving this sort of problem requires the ability to perform
database schema migrations as part of the synchronization process.
Until Django has a migration tool baked in, it isn't really feasible
to have a ManyToOne field.
Even then - we would need to be able to ensure that migrations would
always be able to succeed. For example, what if address was a required
field, and I have existing Users? What value for address_id to those
users receive as part of the migration?
I can sympathize with the intention of the ManyToOne idea. However,
adding this apparently simple idea opens up a Pandora's box of
problems. Forcing 1-N relations to be defined by ForeignKey (and not
by the reverse relation) avoids all these problems.
Yours,
Russ Magee %-)