Extend Django user model with custom fields, receivers and backend - django

I am designing a Django application (v1.6) and need to do several things with users:
Add custom fields, such as a foreign key for user department
Trigger database changes when certain fields change. For example, when the user's department changes I need to move inventory in another model out of the old department and into the new. I was planning to use a pre_save receiver to do this.
Define custom permissions, such as a user can only modify rows in a table that are associated with their department.
Eventually I want to integrate the application with our Active Directory server for authentication.
I looked at the options in the documentation and see that there are several options, from extending the user model with a one-to-one relationship to writing a custom user model.
What design should I use to meet all of the above goals?

Take a look at this blog post: it provides all the design principles to achieve your goals.
http://www.roguelynn.com/words/django-custom-user-models/
I would also take a look here for more information about Configurable User Models, if you want to have your own authentication scheme:
http://procrastinatingdev.com/django/using-configurable-user-models-in-django-1-5/

I also found the following reference helpful: http://www.sofokus.com/blogi/custom-user-model/

Related

Level Specific Access to pages on Django

I currently have a website that has three kinds of permissions:
Active
Staff
SuperUser
What I want to do is limit what a user can view depending on his subaccess level on Driver i.e. Driver has three sub access levels - 100, 200, 300. I was thinking of doing this by
def email_check(user):
return user.accesslevel
#user_passes_test(accesslevel=100)
def my_view(request):
...
How do I add the additional property of the subaccess level to the user model? Is there any other way to implement this? ALso, since this is a an already live project, there are a lot of user on-board already. I'll also need to provide them a default access value.
Your idea to go with user_passes_test looks good to me.
So your main issue is basically how to extend the user model. This topic is covered thoroughly under Django documentation: Customizing authentication.
To sum up, there are mainly two ways to go with. One is to extend your user model with a custom model with an one-to-one relationship with User and any custom fields such as access level.
Alternatively, you can provide with a custom user model and substitute the Django User model, but this seems not appropriate for your case.

Add foreign key in the auth user model

I'm new in Django and I'm trying to add a foreign key in the auth user model. I have different users, and each user has an unique university, but an university can have many users. I'm using django 1.6.
I found a lot of information about using User model as a foreign key, but almost nothing about adding a foreign key to the User model.
It is possible, please read the docs.
There are two ways to extend the default User model without
substituting your own model. If the changes you need are purely
behavioral, and don’t require any change to what is stored in the
database, you can create a proxy model based on User. This allows for
any of the features offered by proxy models including default
ordering, custom managers, or custom model methods.
If you wish to store information related to User, you can use a
one-to-one relationship to a model containing the fields for
additional information. This one-to-one model is often called a
profile model, as it might store non-auth related information about a
site user.

Django Multi-User logins - best approach?

I'm currently developing a Django site in which users can have multiple 'accounts', so that they can seamlessly switch between different public profiles when interacting through the site. What I'm designing is likely to attract multiple registrations per person (and won't be discouraged), I just would like to offer this in such a way as that users can keep the profiles tied together, switch easily and only have to log in once.
The two approaches I've thought up so far include:
One (User model + SiteProfile model) pair and many PublicProfile models per person. AUTH_PROFILE_MODULE is set to point to the SiteProfile model. Issue with this is that I can't easily use per-object permissions: these will be set on the User object and not the public profile, thus permissions to see a page for "PublicProfileA" will also be applied to when the user is masquerading as "PublicProfileB".
One Account model and many (User model + UserProfile model) pairs per person. AUTH_PROFILE_MODULE is set to point to the UserProfile model. This would have the added benefit of the permissions working as intended, and that I can simply have a Custom Backend that will switch users by authenticating a user by if they are currently logged in as another user that has the same Account object as the Foreign Key. Authentication would happen by reading fields on the Account object though, which would mean the password field on every User object would be wasted.
As above, but subclassing Account from User. I've been advised strongly against this though (for reasons unclear).
Is there any pitfalls or better approaches to this? Ultimately, should I use the built-in User model as the one-per-person model that identifies a group of public facing profiles (of which these profiles have a FK back to the User object), or use it as the profile itself, linking back to a single Account object for each person?
Yes, I think the best approach would be to have one and only one User per person and several PublicProfile objects that they can "switch" between. This gives the benefit of only one username/password for them and seems to make the most sense with how Django's auth typically works.

What's the best way to model for various user access

I'm working on a rewrite of an app that has three categories of users
and I'm wondering about the best way to link them to the
authentication system:
In-House Staff,
Contractors,
Customers who interact via the app.
The in-house staff model doesn't store any address info. Contractor
and Customer have some common attributes (address, phone number,
email, etc.) but they have completely different relationships to the
rest of the system.
In the current version I have discrete models for each type and I
manually maintain a link to the equivalent of the user profile table.
But I don't have model inheritance available in the current system.
My question is, do you have any general advice for this and how would
you link it to the existing Auth system, or is there a 3rd party auth
system that you'd recommend I look at.
Thanks.
What you could do is make the user profile model polymorphic. So that whenever you create a user you can add one of the user profile "types" check out: https://github.com/specialunderwear/django-polymorphic-easymode
its documented nicely and always worked for me.

Should I ForeignKey to Django User or a Profile model?

I'm wondering what people's thoughts are on joining models directly to the auth.User object vs to the user's profile model.
I'm storing some different types of models which my user are adding in my app. App users will search for other users via criteria on these models.
On the one hand, I'm thinking that if I join straight to User then I won't need to do request.user.get_profile() each time I need to grab the User's records, and it doesn't presuppose that a User always has a profile (they do in my app at the mo, but still). This leaves the profile model as just containing the user's contact details.
On the other hand, I imagine I'll most likely need values from the Profile (eg name, location) when I'm looking up these other models.
No doubt either will work, so maybe it doesn't matter, but I just wondered what other people's thoughts were.
Thanks!
Ludo.
I would also recommend creating foreign-keys to the User model. It just makes your life simpler when working with the user object in the view, for one. So, you can do things like request.user.foo_set, etc. without having to go through the profile model.
In general: If you want to make your apps reusable, always create foreign keys to User model.
As you already said, in most cases you will need User as well as Profile instance, so to prevent multiple database queries, use cache.
If reusability isn't relevant, create foreign key to Profile and use select_related() to get User instance with single query.