Ok - so, I've been following this thread, and I should probably shed some light on the other side of the decision making process.
I've got a history with Mixins. I was responsible for the final commit of Django's class-based views, which are very mixin heavy… and haven't been universally well received. There was a lot of very incoherent "this sucks" criticism (which -- as an aside -- is hideously demotivating). However, some did find a way to express their criticism constructively; one good example that explains the bigger problem is from one of Django's core team: http://lukeplant.me.uk/blog/posts/class-based-views-and-dry-ravioli/ tl;dr - The root of the objection is that yes, introducing a stack of mixins decreases repetition - but at the cost of a greater learning curve. And as a result, it's harder for newcomers to get started. This isn't an inherently bad thing, but it *is* a tradeoff. So, I've been burned. While I still believe mixins have their place… I'm not rushing to go overboard again. Where does that leave swappable Users? Something like a PermissionMixin? I can certainly see a place for that. Django's permissions model is a very specific beast, and the current User model implements them in a way that could definitely be refactored for reuse. I can certainly see the value in splitting that out so that you don't have to repeat the same implementation, Truth be told, it's about 10 lines of code to reimplement if you import the helper functions, but if someone were to work up a patch for this, I'd be inclined to add it. Something like AdminMixin? I'm not as convinced. The Admin User API interface is duck typing at it's best. Admin doesn't care *how* is_staff is implemented -- it just cares that the attribute is available. Splitting out a mixin class to make it easier to put an is_staff attribute on a model seems like a whole lot of unnecessary complexity Something like PersonalDataModelMixin? Definitely unconvinced on this one. Implementations of first_name and last_name aren't *that* hard, and flexibility to include or not include these attributes was one of the driving motivators behind swappable users in the first place. Now, ok - in the case of the latter two, you could argue that *any* repetition is bad repetition. However, there's repetition and there's repetition. Being forced to repeat hundreds of lines of complex business logic… sure - that's bad. Being forced to explicitly declare that your user model has a boolean flag to define the staff status of a user? I'm sorry, but that's really not an onerous burden, and the CBV experience has shown that it can be beneficial for this sort of thing to be clearly declared, not masked in a superclass or mixin. As for the argument that having the mixins makes it easier to build interoperable components? In this case, I don't buy that at all. Again, duck typing is one of Python's strengths. Interfaces are important, but they don't have to be strong interfaces. It's enough to say "you must have an attribute called X"; you don't have to force a base class with a particular implementation to make that happen. Regarding the specifics -- I'm inclined to agree with Florian on the scope of the PermissionsMixin -- it needs to be constrained in scope, otherwise you're just importing all of AbstractUser into the mixin. So, if someone wants to pull that together (or make an impassioned case the other way), feel free, and I'll see about getting it into trunk before the 1.5 beta freeze. Yours, Russ Magee %-) On Thu, Nov 8, 2012 at 6:21 PM, Ludwig Kraatz <[email protected]> wrote: > If you ask me this just points out to some point i mentioned in the > original Custom UserModel Thread. I'm trying to reframe it again. > I think the current django.contrib.auth *app* somehow behaves like some > mixture of > django.core._mixins_everyone_should_use_to_make_apps_interoperability and > contrib.auth > > As Ross pointed out in this original thread: it is usefull that everyone > uses the AbstractBaseUser - and i'm interpreting now - *because it would be > better for interoperability and security* > I think its possible and not bad designed at all to have this kinda stuff > as core material. > > So - most apps use authorization features as .*has_perm()* or .* > is_superuser*... > > If decoupling it into clear interfaces this could make custom development > much easier without loosing interoperability. i would suggest there > shouldn't be a default user attributes like .*is_superuser* because thats > very restrictive and nasty to workaround. And its clearly an authorization > and no authentication feature. > > So why not having it somehow like this? (pythonic pseudocode) > > core.mixins.authentication: > > *AuthModelMixin*: > -abstract- > > *UniqueIdentifier* > > *get_authentication_id*(): return UniqueIdentifier > *get_long_name*(): return UniqueIdentifier > *get_short_name*(): return UniqueIdentifier > > *DjangoAuthModelMixin*(AuthModelMixin): > -abstract- > > *UniqueIdentifier* > *password* > *last_login* #(for password reset token etc.) > > *check_password*() .. > *set_password*()... > > > core.mixins.personalyzation: > > *PersonalDataModelMixin*: > -abstract- > *first_name* > *last_name* > > *get_long_name*(): return first_name+last_name > *get_short_name*(): return first_name > > > core.mixins.authorization > > *PermissionModelMixin*: > IS_SUPERUSER = "not_as_an_user_attribute_necessarily__is_superuser" > IS_STAFF = "not_as_an_user_attribute_necessarily__is_staff" > > -abstractmethod- > *has_perm*(): > > # or maybe even as property for backwards compatibility > *is_staff*():return False > *is_superuser*(): return False > > > *DjangoPermissionModelMixin*(PermissionMixin): > *has_perm*(permission): return self.is_superuser() or > self._check_for_permission(permission) > *_check_for_permission*(permission): > if permission == IS_STAFF: > return self.is_staff() > else: > super(django1.5a.contrib.auth.User,self).has_perm(permission) > > > and contrib.auth: > > *User*(Mixina,b,c,d): > *date_joined* > > ..... > > > Didn't think abt every detail - just ment to point out what i would > suggest to possibly fit all needs. > > Best regards and sry for this *little* novel > > ludwig > > -- > You received this message because you are subscribed to the Google Groups > "Django developers" group. > To view this discussion on the web visit > https://groups.google.com/d/msg/django-developers/-/36x8Ecpj9scJ. > > To post to this group, send email to [email protected]. > To unsubscribe from this group, send email to > [email protected]. > For more options, visit this group at > http://groups.google.com/group/django-developers?hl=en. > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.
