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:
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 %-)
You received this message because you are subscribed to the Google Groups "Django developers" group.