On Sat, Sep 21, 2013 at 5:49 PM, Timothy Anderegg <
[email protected]> wrote:

>
>>
>>    - 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'.
>>
>>
> One thing to note here, is that AbstractEmailUser would have to define the
> email field with unique=True in order for it to be used as USERNAME_FIELD.
>  This would mean that AbstractUser and User would fundamentally change so
> that email has to be unique.  This could definitely wreck havoc with
> existing apps that don't have this requirement.
>
> One solution would be to have an intermediate class (AbstractNamedUser or
> something) that both AbstractEmailUser and AbstractUser inherit from, and
> each would define their own email fields.  The other would be to stub out
> the email field (email = '') on AbstractEmailUser and actually implement it
> in each descendent class.  I like the former approach myself, since it
> abstracts out name handling and would make it easier to create custom users
> that handle names differently.  It might make sense to put
> AbstractEmailUser above AbstractNamedUser in the inheritance chain, and use
> the stubbing technique too.
>

You're absolutely right about this. Good catch.


>
>>    - 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.
>>
>> The clean_username method is technically unnesseccary, it just provides a
> better error message than the ORM would.  There might be a way to
> generalize this differently.  The other issue is that username is hard
> coded into these forms as a regex validation.  That could perhaps be moved
> to the AbstractUser class itself.
>

Yup.


>
>>    - I haven't looked at views as thoroughly, but I believe them to be
>>    more straightforward. I will do this dive soon.
>>
>> In my experimentation, I haven't had to touch the views at all to make
> things work.  I may have missed something though!
>
> The only other part that would have to change is UserAdmin, although it
> may end up being simpler just to require a custom Admin class for every
> custom user model, since it seems to me abstracting that would be tricky.
>

I don't think there's anything that needs to be done in views either, but I
didn't want to confidently make a statement to that effect and be wrong.
:-) I actually think that the work that would need to be done for the admin
is pretty similar in function to what would need to be done in the forms
case.

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