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.
