On 16 syys, 02:15, Russell Keith-Magee <
russ...@keith-magee.com>
wrote:
> > - The last_login field is in the AbstractBaseUser, but it isn't
> > documented as a required field. Is this field required for something?
> > Is it needed as part of AbstractBaseUser?
>
> Yes, last_login is required - it's needed in order to generate
> password reset tokens etc.
>
> It isn't documented because we *really* want people to be subclassing
> AbstractBaseUser, not building their own User from scratch.
+1 to this.
> > - There is no way to do single-table extension of the default User
> > model. Should there be a way? To me it seems this would be beneficial
> > when dealing with "project profiles". There is little reason I would
> > like to store a required employee number in another table. Maybe it
> > would work if current User was moved to AbstractUser, and User would
> > be class User(AbstractUser): class Meta: swappable =
> > 'AUTH_USER_MODEL'? Quick testing indicates this could work... See
> > commit:
https://github.com/akaariai/django/commit/08bcb4aec1ed154cefc631b8510...
> > - I did a little change to REQUIRED_FIELDS handling in conjunction
> > with create_(super)user(). See commit:
> >
https://github.com/akaariai/django/commit/d9f5e5addbad5e1a01f67e7358e...
>
> > With the above commits I can do this:
>
> > class MyUser(AbstractUser):
> > employee_no = models.CharField(max_length=5)
> > some_other_field = models.TextField(null=True, blank=True)
> > REQUIRED_FIELDS = AbstractUser.REQUIRED_FIELDS + ['employee_no']
>
> > syncb & create_superuser commands work. Admin doesn't work directly,
> > but it seems you can easily subclass the default user admin & change
> > form to make it work.
>
> > Single-table inheritance seems useful to me, and the added complexity
> > to code isn't much.
>
> To be clear -- is this just targeting the "I'm completely happy with
> auth.User; I just want to put XXX on the model" use case? If so, I can
> certainly agree with this; I'll merge these changes in.
Yes, that is the use case. The proxy use case I was worried about in
the other post is about just overriding methods or the manager
without adding any fields. The ability to actually have a _proxy_
isn't important, it is enough you can extend the default user model
easily.
Creating an admin class for no-added-fields extended user model is
somewhat straightforward, although the admin forms currently assume
the auth.User as the base user. I did a little hack to make it easier
to use these forms, see commit:
https://github.com/akaariai/django/commit/04ae5183df8613fd0d91b43834a4582fdf6b0d04
- but I am not totally happy about this approach. If you use an
AbstractBaseUser derived user model, these forms aren't actually
usable.
Creating an admin class for added fields model is also somewhat easy,
you just need to play with UserAdmin.fieldsets to have the additional
fields actually present in the edit form, and you need to make your
required fields "blank=False, null=True", so that the two-stage user
creation works correctly.
> > BTW: I did also a little test to allow select_related() for user
> > profiles:
https://github.com/akaariai/django/commit/81f91db3234110b90572b25ca69...
> > - the idea is that the profile models could just to
> > get_user_model().SELECT_RELATED_MODELS.add('user_reverse_name'). I
> > wonder if we want something like this now/later...
>
> Possibly; but if we do, I'd rather attack it at the model Meta level
> -- i.e., an analog to Meta: ordering that applies a select_related
> automatically to every queryset.
Rethinking this, and I don't see the need anymore. It is now possible
to control the user model's manager, so you can just override
get_query_set() and use select_related() manually. Automatic
select_related/prefetch_related could be good for other use cases,
though.
Some additional findings:
- The get_by_natural_field() manager method has a bug: getattr(self,
'USERNAME_FIELD', ...) should be getattr(self.model,
'USERNAME_FIELD', ...)
- Do we want to future-proof some of the interface methods by adding
**kwargs to the method signatures? At least has_perm /
has_module_perms seem like possible candidates.
I wonder if we want to do something about allowing easier password
handling in (admin)forms for custom user classes. Currently making an
admin class for your user class is somewhat hard - you need to either
dig out what auth.admin does for the password field or reinvent it
yourself.
In total this is looking really good, but I can see the need to do
additional polish for some time. Maybe we could take a somewhat
relaxed approach to what constitutes a feature addition when it comes
to this feature? To me it seems there might be something we want to do
about the password forms for example. But, I am not sure we can get
that something done about this by the end of month...
- Anssi