Hi Jian,

Apologies for the delay in responding.



On Thu, May 8, 2014 at 9:44 AM, Jian Li <j...@jianli.us> wrote:

> Hi Russ,
>
> Thanks for the feedback!
>
> I believe the proposed code already addresses points 1-4.
>
> 1) The implementation does in fact return the correct natural key,
> `(self.username,)`, for the User model.
>
> 2) When multiple fields have `unique=True`, the implementation does not
> choose from among them; it returns a tuple containing *all*
> non-auto-generated unique fields.
>

Ok - I can see how that could work. I don't necessarily agree that it's
obvious, since it would produce an over specified key - but from a
technical perspective, it would work.


> 3) In the presence of multiple `unique_together` tuples, the
> implementation arbitrarily chooses the first one.
>
> 4) In the presence of both `unique_together` fields and `unique` fields,
> the implementation arbitrarily goes with the former.
>

My apologies - I didn't catch that in my scan of your implementation.


> You can see the specific algorithm at line 1422
> <https://github.com/jianli/django/commit/b6d644b45c379cae83f7f2609525e616b62ade52#diff-507b415116b409afa4f723e41a759a9eR1422>
> .
>
> The implementation always chooses a natural key which uniquely identifies
> the relevant model. The choice may be arbitrary in the presence of multiple
> cues, but so is any individually-implemented choice of a natural key.
>
> At the very worst, if the user does not agree with the choice for the
> specific model, they can fall back to individually implementing the natural
> key for that model; this is no worse than the current situation. So I would
> argue that the base implementation proposed here is strictly better than
> the status quo.
>
> In the course of serializing about a dozen different models, I've found
> this to be a very useful base implementation that has saved me from the
> tedium of writing many lines of boilerplate.
>

That's the thing - I don't see it as boilerplate. I see it as a behaviour
that *should* be explicitly defined, not implicitly derived from a model
definition.

Here's another example why: Changes in schema.

You build some models, and generate some fixtures. Then you add a new
unique field to your model (or remove one). You try to load your fixtures -
and the load fails, because the serialisation scheme has implicitly
changed. Ok, sure - you could work your way out of the problem by
introducing a temporary manual definition for the serialiser, but the whole
problem would have been avoided if you'd just used a manual definition in
the first place.

This is one of those times where dogmatic adherence to DRY is a bad thing.
DRY doesn't mean you don't ever type the same thing twice. It means that
you don't ever express the same *concept* twice. And in this case, the
structure of your natural keys is a concept that is independent of the
uniqueness constraints in your model - they're related concepts, to be sure
- but they're independent.

So - I'm still -0. If I had to provide an alternative, I'd say that a Meta
definition to allow you to explicitly define your natural key:

class MyModel(Model):
    ...
    class Meta:
        natural_key = ('field1', 'field2')

that then automatically rolls out into the appropriate definitions (but
would be overridden by manually defined key functions) would be a
preferable solution - but we're talking about 2 methods that are, for the
most part, 2 lines of code each. I just don't see the overhead of defining
natural key functions as something that is particularly onerous, and the
overhead involved in building, maintaining and testing automated (or
semi-automated) natural key functions just isn't worth it, IMHO.

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 django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
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/CAJxq848ATeV-YQV5MRK9R82pBRFubVQjtA%2B9FsJvAkMOVn45sA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to