I'm taking several different e-mail replies and attempting to conglomerate 
them. Please forgive me if this is not considered socially acceptable here.

On Sep 20, 2013, at 8:42 PM, Russell Keith-Magee <[email protected]> 
wrote:

> We have two key questions here:
> 
>  1) Where does the new model live? Is it going to live in contrib.auth, or in 
> a new contrib.email_auth package?
> 
>  2) Exactly what does the new class hierarchy look like? Are we going to do 
> any refactoring of AbstractUser? How many composable bits are we going to end 
> up with?
> 
> We've had a lot of discussion on question 1, which is risking becoming a bit 
> of a bikeshed on the interpretation of `swappable`. 
> 
> What I haven't seen is a whole lot of clear discussion on point 2. Most of 
> the discussion seems to stop at "use package/patch X", rather than a 
> providing a good  summary of the consequences. 

I think you're making a good case that some of the question 1 discussion has 
been cart before horse. Perhaps it would be better understood if we did some 
more discussion on the other half.

Here's what I am thinking we should do (wiki segment forthcoming):

I believe that we should add an AbstractEmailUser as a subclass of 
AbstractBaseUser, and make AbstractUser subclass it.
So, right now we have AbstractBaseUser -> AbstractUser -> User.
My desired hierarchy would be:
AbstractBaseUser
AbstractEmailUser
AbstractUser
User
EmailUser
I assume this is mostly intuitive, but under my proposed hierarchy, everything 
that AbstractUser has now would be moved to AbstractEmailUser except for the 
username field. AbstractEmailUser would have USERNAME_FIELD set to 'email', and 
REQUIRED_FIELDS set to empty tuple. AbstractUser would have USERNAME_FIELD set 
to 'username' and REQUIRED_FIELDS set to ('email',).
Both User and EmailUser would have the swappable Meta option set to 
'AUTH_USER_MODEL'.
I would then propose taking forms that hard-declare username as a field (e.g. 
UserCreationForm, but there are others) and instead determine their username 
field using the `fields` meta option in ModelForm.
An example in the case of the UserCreationForm would be: fields = 
(model.USERNAME_FIELD, 'password1', 'password2')
There's a potential land mine in here which is that the `clean_username` method 
is much less straightforward: we'd either have to determine the method name 
programmatically in class construction or get around the issue through 
double-defining it. I would favor the former because then the form is useful 
without modification to more third-party use cases. However, this is one of the 
(few, IMO) cases where there actually is a complexity hit, and I believe this 
problem should be noted as a disadvantage of my approach.
I haven't looked at views as thoroughly, but I believe them to be more 
straightforward. I will do this dive soon.

> This all hinges on the interpretation. My intention was *not* that swappable 
> meant "This model might not be loaded". My intention *was* that swappable 
> meant "This particular model is an extension point that might be replaced by 
> a third party." 


But my proposed usage of swappable is within this intent.

My argument is that User is marked swappable, meaning that this particular 
model is an extension point that might be replaced by a third party. My 
argument is also that EmailUser should be marked swappable, meaning that this 
model is an extension point that might be replaced by a third party. :-)

The spot where I'm potentially outside original intent is that replacing User 
with EmailUser isn't *technically* a third party replacement, but any option so 
far proposed technically goes outside this. Therefore, I honestly believe that 
my proposal is within your original intent.

> And this remains my biggest reason why the first interpretation isn't the 
> right interpretation. We shouldn't be encouraging people to build monolithic 
> apps containing dozens of "swappable" models. We should be encouraging people 
> to write small, tight apps that fill a single purpose.


But does that mean it's the right choice in this case? As best as I can tell, 
we're talking about a non-trivial amount of code duplication to create a 
separate app for this (duplicate model, duplicate forms, duplicate views...). 
And shouldn't we also be encouraging people to follow the DRY principle? A 
separate app very much doesn't.

> And, flipping it around -- I'm not trying to be confrontational either - also 
> just looking out for the best interests of Django (as I see them).


Of course! My motivations are similar...I want to contribute the best patch I 
can. :-) There is no shortage of good faith here, methinks. And it's a really 
interesting question. :-)

On another note, I've been on vacation recently, but I am setting aside time to 
work on this this coming week, whether that involves commenting on / improving 
Tim's implementation, or doing some alternate implementation if a different 
approach is accepted.

L

-- 
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.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to