also sprach Tim Graham <
timog...@gmail.com> [2015-12-08 22:38 +0100]:
> I'm having trouble understanding the problem. Could you give some example
> models and code that demonstrates it?
Gladly. The code I am talking about is here:
https://github.com/madduck/wafer/blob/147-kvpairs/wafer/kvpairs/models.py
https://github.com/madduck/wafer/blob/147-kvpairs/docs/kvpairs.rst
but I'll try to give the quick rundown here too:
Basic requirement: avoid creating new database fields for all the
various random needs around conference management. In the past, we'd
add to the UserProfile fields to hold t-shirt size, payment and
arrival status, day trip participation etc. and the database just
grew and grew. We're now switching to this new "wafer" and would
like to ensure that this doesn't happen again.
So while there are some profile attributes for sure that are core
and will go into the profile table, others aren't and we'd really
rather treat them as throw-away, quick'n'dirty data, which they
often are.
Hence I created this key-value store. At the core, it just attaches
two text fields "key" and "value" to an instance of a model (e.g.
a scheduled talk), and GenericForeignKey would be just perfect for
this.
But we also wanted to collect a bit of information about a Key and
add a bit more structure. For the moment, Key instances just hold
information about owner and group for access control and
namespacing, and, well, the model to which this key applies (also
used for namespacing).
Here's what it looks like:
+-- ContentType --+ +-- Key ----+ 1 +-- KVPair --+
| ID |-. | ID |---. n | ID |
| app_label | \1 | owner | `--| object_id |
| model | \ | group | .--| ref_id |
| name | n\ | name | n| | value |
+-----------------+ `-| content_t | | +------------+
+-----------+ |
1| +-- Talk --+
`--| ID |
| title |
+ … -------+
The problem is that GenericForeignKey expects content_type and
object_id to be in the KVPair model, but content_type is in the Key.
There's still a 1:n relation between ContentType and KVPair, but
it's indirect.
You might rightfully ask why we don't just throw the Key fields into
KVPair and be done with it. Sure, that is a solution, but you'll
also concur that it'll involve a lot of duplicate data and make
unique constraints a lot harder. It'd seem a workaround at best for
the limitations around GenericForeignKey.
But if GenericForeignKey could just be appeased by telling it "yes
I know you want content_type in the same model, but trust me, if you
use the attribute of this related object, you'll get the same", then
it'd work out.
To me, the even better solution would be to give Key the right
accessors to make GenericForeignKey happy, such that GFK doesn't
even need to care about what kind of object it's being asked to
refer to, as long as it gets the data it needs. I have toyed with
the idea of making Key a subclass of ContentType, but that creates
a slew of other problems, and doesn't address the fact tat
GenericForeignKey actually compares the instance class with the
hard-coded string "contenttypes.GenericForeignKey".
Does this make more sense?
an egg has the shortest sex-life of all: if gets laid once; it gets
eaten once. it also has to come in a box with 11 others, and the
only person who will sit on its face is its mother.
spamtraps:
madduc...@madduck.net