On Wed, May 7, 2014 at 10:20 AM, Jian Li <[email protected]> wrote:
> Hi!
>
> In the course of implementing `natural_key` for many different models,
> I've noticed that the implementation is fairly predictable; it tends to use
> the fields already marked as unique. To avoid writing a separate
> implementation for each model, I've written a patch that implements the
> relevant logic on the model and manager base classes:
>
> https://github.com/jianli/django/compare/default-natural-key-implementation
>
> https://github.com/jianli/django/commit/b6d644b45c379cae83f7f2609525e616b62ade52
>
>
> Details:
>
> - The proposed implementation is recursive, which enables it to create
> natural foreign keys even when the foreign key structure is arbitrarily
> deep.
>
> - When a natural key is not available but the user specifies
> `--natural-foreign`, the proposed implementation will raise an exception.
> This is inconsistent with the current behavior of silently falling back to
> using the "artificial" foreign key. However, I would argue that this is the
> correct behavior, and also the behavior implied by the documentation; if
> the user wants a natural foreign key serialization and Django is not able
> to provide it, Django should let the user know with an exception.
>
> - I was unsure whether to add the model method to `ModelBase` or `Model`.
>
> - I've manually tested a nearly identical patch against 1.5.4, but haven't
> had a chance to test against the development version.
>
> Please let me know what you think, and keep up the amazing work!
>
Hi Jian,
What you've proposed is an interesting idea, and a magnificent example of
what you can do by exploiting the contents of _meta - but as a proposal for
Django's core, I think it falls down in a couple of critical places.
1) A model without unique_together can still implement natural key. For
example, the User model has a natural key, but doesn't have a
unique_together clause. So, if you've just go a unique field, you can still
have a natural key, but this helper won't help.
2) Assuming you can resolve (1) (which wouldn't be that hard in practice),
multiple fields on a model can have unique=True set. How do you pick which
one is *really* the natural key?
3) A model can have *multiple* unique_together clauses. Your code only
appears to handle the case of "unique_together = ('field1','field2')", but
it's also legitimate to say "unique_together = [('field1', 'field2'),
('field1', 'field3')]" - i.e., multiple independent unique_together
clauses. Again, how do you pick which one is *really* the natural key?
4) What about if you have multiple fields with unique=True *and* multiple
unique_together clauses?
5) Even if we could resolve those issues, there's a backwards compatibility
issue implicit in changing behaviour around serialisation, and Django (as a
project) is very sensitive to those issues.
There *might* be a solution that covers problems 1-4, and maybe even
problem 5; but that solution is almost certainly going to be declarative
(i.e., naming which field/field pair is the natural key). However, once
you're declaring the fields that are your natural key, you're 90% of the
way to an implementation of get_natural_key() -- so you have to ask why
bother developing and maintaining a moderately complex automated method for
something that isn't that hard to declare explicitly in 2 lines of code.
So, I'm -0 on this as currently proposed. If you've got any creative
solutions to these problems, please raise them. The broader principle of
having models have useful properties by virtue of their basic definition is
appealing to me. I'm just not convinced that based on the details you've
presented so far, we would get a net gain.
Yours,
Russ Magee %-)
--
You received this message because you are subscribed to the Google Groups
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-developers/CAJxq84-1ENdKbGPPbRAOFqXxmunCWxgxxwvyyaUR6rBQ1Exajw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.