Django - Cannot login when subclassing User model - django

I searched for a similar question but found none so far.
I have a subclass of User (django.contrib.auth.models.User). I want my site to support both Individual users and Business users, so in this case it's:
class BusinessUser(User):
website = models.CharField(max_length=20)
objects = UserManager()
I have a register form that saves a user as a User and another one that saves my user as a BusinessUser. The problematic case is the BusinessUser:
I have checked through the Django console that both an User and a BusinessUser object exists after registration of a BusinessUser, and all fields are fine (username, email, password).
However, on my login page, I cannot login with my BusinessUser's. I can login fine with the normal User's registered, but not BusinessUser's.
Does anyone know what might be wrong?
Thank you.

Custom authentification backend should be used when django's User subclassed
You can see example here
I haven't tested this, but I believe this will work.

You subclassed User. Don't do that ever. Use profiles to add additional data, and if you really need two separate models (say for having two separate views for individual and business users in the admin) create proxy models and custom managers that filter only individual or business users from User.

Related

How to structure django admin for multiple users

I'm still a complete newbie on Django, so now I'm a little bit lost on what I could do to structure my server to suit my needs.
The situation is like this: my Django admin could be accessed by the admin and multiple users. Each user can add multiple item to the server, and the server will only allow them to retrieve, modify and delete item added by them and not the other users. They will also have some custom option they can pick: like receiving notifications through emails or another channels. Meanwhile, admin can see all items, and have a filter to see all items added by one user and all users's custom option.
Any help would be appreciated.
take a look here. this is where i started with custom user models. https://wsvincent.com/django-custom-user-model-tutorial/
Django has builtin user models with basic fields like username email and password and authentication. The above link will help you create custom user models and it will be a good place to start

Custom User model for Django with Facebook Login

On the client side I use the iOS SDK for Facebook to login and I get the Facebook ID and the access token.
Now on the Django side of things I would like to create a user with Facebook ID as the primary identifier and other fields like access token, first name, last name etc (the last two of which I will retrieve from the Graph API on the server side).
I know that I have to create a custom user model.
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.
This will not be enough as I will be using the Facebook ID and the access token for authentication.
This leaves me with two options: I can substitute a custom user model like so:
AUTH_USER_MODEL = 'myapp.MyUser'
Or I can subclass AbstractUser:
If you’re entirely happy with Django’s User model and you just want to
add some additional profile information, you can simply subclass
django.contrib.auth.models.AbstractUser and add your custom profile
fields.
But that doesn't sound quite right either. Also this design tip has confused me a little more.
Model design considerations
Think carefully before handling information not directly related to authentication in your custom User Model.It may be better to store app-specific user information in a model that has a relation with the User model.
What is the best way to implement what I am trying to do?
Just a side note: The problem of a custom user is that it is often the case that other apps (and yes, you will use them) don't interact correctly with it due to the assumptions they make on the base model for auth.
This will not be enough as I will be using the Facebook ID and the access token for authentication.
I'm not sure you really need a custom user. For instance, I'm using open id for authentication and there is no problem in using the default user: there is just another model with a OneToOne relationship to the default user.
The main concern you should have for a Facebook ID for authentication (and authentication in general) is to have a custom authentication Backend with its own specific facebook authentication.
Internally, authenticate() runs through all installed backends (settings.AUTHENTICATION_BACKENDS) and tries to authenticate the user with one of those.
You can search some of the existing implementations e.g. in Django packages for facebook authentication.
If your users should be enabled to login/register with username, mail and password -> use a OneToOne relationship to django's usermodel to store facebook credentials.
If your usermodel entirely depends on facebook data and you don't want your users to login with username/pass -> substitute the usermodel with AUTH_USER_MODEL = 'myapp.MyUser'.
You might also want to take a look at django-allauth which solves much of your problems in a sweet little package.

Multiple User Types For Auth in Django

My web features two user types, Client and Professional. There are also two 'main modules', one for clients to buy stuff and so on (the main site), and the other for professionals to manage operations. For auth, I would like to have:
A single 'sign in' form, which detects whether the user is a client or a professional and forwards her to the right module (main site or management site).
Two 'sign up' forms, one for clients and other for professionals. Probably, the site will ask the user whether she wants to register as a professional or as a client, to trigger the right registration flow for each case.
Clients will use the 'main site' and should not be authorized to use the 'management site'.
Professionals will use the 'management site' but should not be authorized to sign in to the main site.
Both professionals and clients are registered as Users, and share common fields, such as username, phone, email, etc...
Since Django won't let me use two models for authentication. I've created custom model subclassing AbstractBaseUser and which serves me as a base auth class for Client and Professional.
class BaseUser(AbstractBaseUser):
...
class Client(BaseUser):
...
class Professional(BaseUser):
...
I've also changed the AUTH_USER_MODEL setting to:
AUTH_USER_MODEL = 'myapp.BaseUser'
I've also included django-allauth to manage user registration and authentication. But now I'm stuck. I just began playing with Django/Python and I'm not sure how to solve this.
It seems there is no official recommended way for doing this (Implementing multiple user types with Django 1.5). Should I stick to the subclassing approach, or should I do the OnetoOne relationship pointed out in the docs ?
Once I have the models properly setup, how should I proceed with the two registration forms? Is it possible to accomplish this with django-allauth, or do I need to do it manually?
As far as I know, when a new user is registered, a new base user is created in the User table. But since I will be creating user specializations (Client or Professional), how should I specify that I also want to create the client-related data or professional-related data in the corresponding table?
I'm pretty new to Django, so any advise will help
I think the easiest way for you to do what you are talking about is going to be to have 3 apps in your project: your top level app, a "professional" app and a "client" app. At the top level app, all you really need to do is give the users a login form, and 2 links, one for registering as a Professional and one for registering as a Client.
In this case, I believe it will be easiest for you to use Django's built in Permissions system, and assign each type of user to a corresponding group (eg. professionals and clients). You can use a decorator on your views to ensure that only members of a particular group can access that view (since you have 2 separate apps for each group, you can add a decorator to all views in each of them, or you can import Django's authorization functions into your urls.py and check it there, although that is beyond the scope of this answer).
Registration is easy enough, use your urls.py file to forward the user that wants to register to the correct app. Once you do that, you should be able to use django-allauth registration on each app, allowing you to create 2 different kinds of users. Make sure when the register, you assign them to the correct group membership.
As for the login redirection, once you receive the POST data, I would check for which type of user logged in, and use that to forward the user to the correct URL that goes with the Professional or Client app. You can see the below link for an idea of redirecting a user after login.
Django - after login, redirect user to his custom page --> mysite.com/username

django staff users manage their own users only

In my Django app a user can register to the site and receive staff_user privileges from the admin.
After that the staff user can create and manage some other users (normal users) using default django admin site.
Now, I would like to let the staff user see and manage only the users he created from the admin site, I don't want him to see other users created by another staff user.
how can I do that? I imagine I need to modify admin.py right?
Don't modify the admin site.
In general, you have the following tools available:
Create groups
Add users to groups
Create custom permissions on your models, to indicate certain actions
https://docs.djangoproject.com/en/1.4/topics/auth/#custom-permissions
However, what you are asking: Now, I would like to let the staff user see and manage only the users he created from the admin site is not possible in django-admin.
The Django-admin site is only intended as a glorified development tool for fully trusted users, not as a customizable app for end users.
If your project requires an admin site with any of the following ...
Customized administraion functionality.
Exposure to any user that is not completely trusted.
... then I'm afraid you have to create your own custom app.
You can replace the stock UserAdmin with your own which overrides queryset() and does the filtering. The bigger issue is what to filter by. The default User model does not store a "created_by" in the model instance. So you would need to add this information whenever a User is added.
How best to do this depends on your Django version.
Django 1.5 introduced a "Configurable User model" which makes this very easy.
https://docs.djangoproject.com/en/dev/releases/1.5/#configurable-user-model
In earlier versions you would either have to monkeypatch the User model, or store that information in a separate "user profile" attached 1:1 to the User.
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
Regarding the trusting of users (which wasn't a topic but I feel the need to comment on thnee's answer) in the Django admin, check out the links in my answer here: Should I use Django's Admin feature?

django user authentication, shoulid admin be used or created from view?

I am completely new to Django. I have done all the tutorials and would now like to create a simple user authentication to be able to access a page in my site.
My question is as to whether I should use the admin authentication? Or should I create my own customer view with a user name and password and use the DJango authentication api?
To clarify, I have a page that I want secured and to only be view when a user has permission to view it. Is this a reasonable thing to do in the built in Django admin? It seems the Django admin is for giving permission to create new records related to an apps model.
Thanks!
I would prefer using Django's built in authentication system. Lets assume that you'd want to create you own customer model with say mobile number and twitter handle, you can extend Django's User model by following
from django.contrib.auth.models import User
class Customer(User):
mobile = models.CharField(max_length=12)
twitter = models.CharField(max_length=100)
In this case not only would you inherit attributes like email, username etc from Django's User model but you'll also add you custom attributes that you can store in database.
The easiest approach to securing your pages would be to use login_required decorator. Also take care of including right URLs while securing your pages to make sure you have included Django's login and logout URLs