I have different apps in my django project. I want to keep an independent app for auth&auth that is reused in all apps. The auth&auth app is one app with my basic custom user model. This user needs to log in with email so I am inheriting from AbstractBaseUser instead of extending the User class. Now in all apps the login is same way, basic user attributes are same; but some apps add additional fields like 'salary', others use the model as is. So what is the best way to reuse the Custom User model I created in my login app? If I inherit the concrete class, I'll have 2 tables. If I declare the Custom User class abstract, how will I use its functionalities, roles and permissions?
I think the best way to achieve what you are asking for is:
class Learners(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, unique=True)
nick = models.CharField(max_length=12, unique=True)
#Many to Many relationship with course
courses = models.ManyToManyField(Course, blank=True)
def __str__(self):
return self.user.get_full_name()
Where the AUTH_USER_MODEL is set to the Custom User model, inheriting from AbstractBaseUser, that you created, like this : AUTH_USER_MODEL = 'courseSystem.MyUser' in settings.py for the main Django project. In my example courseSystem.MyUser is the Custom User Class defined.
I am sharing this from a similar situation you have described above, that I am working on.
In the above example, if you were to make the custom MyUser class as abstract and then inherit the Learners class from it:
class Learners(MyUser):
then Learners class would no longer be a models.Model type class but the concrete User class for that app, and in each case i.e., for each such class ineheriting from the abstract MyUser class, you would have to overload the necessary members of MyUser required for a concrete user class for Django. Also since you are using AbstractBaseUser and not extending on default User class, you would have to define custom User forms, and User Managers for your custom user class. So if you have a concrete MyUser class, as in the example above, you can define the custom User Manager and User Forms for MyUser once, and keep one-to-one relationship to it from your models in different apps. But if you make the MyUser class as abstract, you wouldn't define User Forms and User Managers for MyUser, but separately for each of your apps where you form a concrete user class by inheriting from this abstract Custom User class.
https://docs.djangoproject.com/en/1.9/topics/auth/customizing/
Related
I've seen two ways of extending the User model in Django.
Method 1:
class User(AuthUser):
new fields...
Method 2:
class MyUser(models.Model):
user = models.OneToOneField(User)
new fields...
What is the difference between them?
The first one is multi table inheritance. (I presume you are actually speacking of django.contrib.auth.models.User here). Your new User model will have all the field that are defined in django's user model. This is managed by django implicitly creating a OneToOneField on your model.
The second, one you are creating the OneToOneField yourself. Now the django.contrib.auth.model.User model's fields do not automatically appear as parts of your own model. YOu can still access them as
myinstance.user.parent_field
Having said all this, for option 1 you should inherit from an abstract base class rather than directly from the User model.
class MyUser(AbstractBaseUser):
...
I want to implement users in my system. I know that Django already has an authentication system, and I've been reading the documentation. But I don't know yet the difference between
from django.contrib.auth.models import User
class Profile(User):
# others fields
And
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User)
# others fields
I don't want to know why to use one or another, but what happens under the hoods. What's the difference?
Your first example is multi-table inheritance.
class Profile(User):
If you have a profile, you can access all the fields on the user model directly (e.g. profile.username and profile.email). In this case, Django creates a OneToOneField for you automatically.
The second example is a regular OneToOneField.
class Profile(models.Model):
user = models.OneToOneField(User)
In this case, you cannot access profile.username and profile.email. Instead, you access these fields via the one to one field (e.g. profile.user.username and profile.user.email).
In your case, where you are adding a profile model, I would avoid using inheritance, and use a one to one field instead. The User model has custom admins to handle passwords. If you use multi-table inheritance, then your Profile model would have to handle this as well. By using a one-to-one field, the custom admins can handle the user fields, and your Profile model admins only have to handle the additional profile fields.
Another option is creating a custom user model. In this case you subclass an abstract class AbstractUser or AbstractBaseUser instead of the class User. If your Profile class works, then I would recommend this instead of the custom user model, because custom user models are more complicated to set up.
I would like to separate users of my Django app in two classes :
- Admin (users that use Django admin) - inherit from AbstractUser
- User (customers users) - inherit from AbstractBaseUser
I want to separate this two kinds of users because all fields of AbstractUser (is_staff, is_superuser, groups, permissions) are useless for my customer users and for permissions and group, I just want to implement something different. That why, I want to use AbstractBaseUser.
But for django admin users, AbstractUser class, it's just perfect and particularly with permissions feature.
class Admin(AbstractUser):
pass
class Customer(AbstractBaseUser):
pass
But now, is there a way to precise the User model used Admin for the django admin only?
And use the Customer model for the rest of my apps.
Did I have to implement this from scratch :
class MyUser(AbstractBaseUser):
username = models.CharField(max_length=30, unique=True)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField()
is_active = models.BooleanField(default=False)
class Admin(MyUser, PermissionsMixin):
is_staff = models.BooleanField(default=True)
class Customer(MyUser):
# specific fields
pass
With this implementation, if I set AUTH_USER_MODEL to User, permissions will not work because User has no permissions, is_superuser and is_staff fields.
And if a set it to Admin, I will not be able to authenticate Customers with django.contrib.auth.
So guys do you have a solution to this issue?
The way Django offers to you seems to be much more flexible and future-adapted.
You have a built-in User model, which you can override. Anyway, that model has permissions, groups, etc.
If you need different field sets for different kinds of users, you create a OneToOne profile models.
The separation point between your admins (actually, staff users) and regular customers is a User.is_staff attribute.
This way you gain a bunch of cool stuff (compared to two completely different user models):
Everything works out of the box: contrib.auth and contrib.admin modules.
Easy-customisable separation point: just override the admin_site.has_permission() and here you go.
You have the ability (but not obligation) to create users which are either customers and admins.
You can assign groups and permissions (different from your admins' ones) to your customers. Even you don't need it now, who knows.
As for drawbacks. The only one you've pointed out so far: your customers will be having (unused for now) permissions. Well, as they (as well as groups) are just separate tables, your customer data will have no performance of storage overhead.
That is to say, the overhead is negligeable compared to the benefits. I'd strongly recommend staying with Django's default User model and extending it if necessary.
I want to implement users in my system. I know that Django already has an authentication system, and I've been reading the documentation. But I don't know yet the difference between
from django.contrib.auth.models import User
class Profile(User):
# others fields
And
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User)
# others fields
I don't want to know why to use one or another, but what happens under the hoods. What's the difference?
Your first example is multi-table inheritance.
class Profile(User):
If you have a profile, you can access all the fields on the user model directly (e.g. profile.username and profile.email). In this case, Django creates a OneToOneField for you automatically.
The second example is a regular OneToOneField.
class Profile(models.Model):
user = models.OneToOneField(User)
In this case, you cannot access profile.username and profile.email. Instead, you access these fields via the one to one field (e.g. profile.user.username and profile.user.email).
In your case, where you are adding a profile model, I would avoid using inheritance, and use a one to one field instead. The User model has custom admins to handle passwords. If you use multi-table inheritance, then your Profile model would have to handle this as well. By using a one-to-one field, the custom admins can handle the user fields, and your Profile model admins only have to handle the additional profile fields.
Another option is creating a custom user model. In this case you subclass an abstract class AbstractUser or AbstractBaseUser instead of the class User. If your Profile class works, then I would recommend this instead of the custom user model, because custom user models are more complicated to set up.
I have a question about django's user inheritance.
I have gone through docs of django where I have seen inheritence of User model if I want to register the user through email and password.
My questions :
What will be the difference on default User model and Custom User model that I will make ?
Can I use the permissions and add group in the Custom User model ?
And also what if I want to inherit django's default User in my model ?
class Person(User):
address = models.CharField(max_length=100)
def __unicode__(self):
return self.address
Here the user model is django's default User model ?
Can I inherit like that ?
based on django specifying a custom user model
The easiest way to construct a compliant custom User model is to inherit from AbstractBaseUser. AbstractBaseUser provides the core implementation of a User model, including hashed passwords and tokenized password resets.
Alse Extending the existing User model can be a good option.