The last week I've been looking into related fields and all that
stuff. As it turns out, the issue is much more complex than I
originally anticipated and at the moment I have some doubts whether
this can be achieved as part of this GSoC.

Basically, there are two approaches to the task:

1) Make ForeignKey and friends the field that manages all its rows
   (i. e. it will return multiple columns when asked for them and so
   on).

2) ForeignKey will be just a virtual field and it will create all
   required auxiliary fields in the local model. ForeignKey would then
   just handle the relationship stuff and leave everything else to the
   aux fields.

Some notes about both of them (I spent a few days trying to make
either support at least some basic features and both seem bloody
complex to me):

1) The changes required to ForeignKey itself can be kept to a minimum
   but this would require drastic changes in many parts of the
   internal code:

    * a complete rewrite of the database creation code

    * probably also a rewrite of the parts that match rows fetched
      from the database to model fields

    * many internal changes in query code to support multi-column
      fields

   Basically, the problem is that practically all parts of the code
   rely heavily on the fact that each local field is backed by exactly
   one database column (except for M2M which is often special-cased).

   Now, all of this code would need to be rewritten to also work with
   fields spanning several database columns. I got completely lost
   somewhere around SQLCompiler.resolve_columns and
   DatabaseOperations.convert_values, though this is all just the tip
   of the iceberg that I encountered while looking into raw querysets;
   there is much more to it for regular ones.

2) This would require an extensive refactor of related fields. I can
   imagine making the aux field sit at ForeignKey's attname to manage
   the actual value. This would give us creation and row matching
   practically for free, but again, some internal query changes would
   still be necessary (multi-column joins, for one).

   The change could be made backwards-compatible if we made the
   default aux field use the ForeignKey's db_column.

Of course, it might be possible to make a half-assed hacky solution,
i. e. ForeignKey would be a full-featured field in some cases and a
virtual one otherwise but this would make a total mess out of
everything and it would require a serious amount of nasty hacks and
workarounds.

At any rate, I don't feel competent to make the decision in this
matter and I honestly believe there ought to be some discussion about
which route we'll take.

My personal favorite is the second option but I can imagine people not
liking code that adds local fields automagically. On the other hand,
there is already one such case (the id AutoField).

Anyway, now is the time that I'd like to see some comments and
opinions of other people who know the ORM code.

Michal

Attachment: signature.asc
Description: Digital signature

Reply via email to