extending default User model in Django - django

I've written my first application Django 2.0.
Everything is working fine and the application is almost ready when I realized to replace id primary key field from default integer type to UUID to make database entry more secure.
When I searched for this how to change id of user table to UUID I got many tutorials extending AbstractBaseUser.
Here is I have written own User model.
account/models.py
class User(AbstractBaseUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
But I'm confused more with examples on different sources.
Every example is adding few more fields in extended model like
first_name
last_name
is_staff
is_admin
active
and functions as
def get_fullname(self):
def get_shortname(self):
etc.
I think all these fields and functions are there by default in AUTH_USER_MODEL.
Does extending AbstractBaseUser overwrites AUTH_USER_MODEL and it is required to add all fields which is there by default?
also, I'm using settings.AUTH_USER_MODEL as foreign key in different models. Should It be replaced by account.User model?
I'm also using django-allauth plugin to enable login using the social network and use email only for authentication. Do I require to add email field in the extended model with unique=True?

Django AbstractBaseUser provides only following fields: password, last_login, is_active. So if you are using custom User model inherited from AbstractBaseUser you need to define all other fields such as email manually.
As another part of question just adding AUTH_USER_MODEL = 'users.User' to your settings.py file should make everything works without replace code in your project.
UPD
If you need field like first_name, last_name, etc. to be includet to the model you can use AbstractUser instead of AbstractBaseUser.

As the Django documentation indicates, it's difficult to extend the User table after-the-fact, and not recommended at all for apps. A better way is to create an auxiliary table which has a 1:1 relationship with the user-id. Leave Django's user-table alone and just use this other table to pony-up to it.
The "Django Annoying" project, at https://github.com/skorokithakis/django-annoying#autoonetoonefield, has some very useful "juice" to make this much easier: an AutoOneToOneField. Whereas Django's foreign-key field will throw an error if an record doesn't exist, this field will automagically create one on-the-fly, thereby side-stepping the entire issue. (The documentation page linked-to above shows exactly how this is done.)

Related

Different model field requirements for superuser vs normal user? django

Example(not true example):
I want the superusers to have to save on register their username and email.
and the normal users to save username, email, and a number(unique=True).
I wanted to use the user models django has, but I don't see how when the number has to be unique? or rather I originally wanted it to be the primary key, but only for normal users. Do I have to manually make two different user classes along with the permissions, authentication etc.? or is there separate user models for admin/user in django?
I tried(as a complete amateur, new to oop and django)... after gave up on using it as primary key, bc AbstractUser is fly.
Tried with onetoonefield, but couldn't make a combined form with UserCreationForm, bc "too many fields error". Also weird to have an important part of the user table be in a different table (or is it?).
something like (not 100% accurate):
#in models.py
class AdminUser(AbstractUser):
username
email
class NormalUser():
ontoonefield(AdminUser)
number(unique=True)
#in forms.py
class NormalUserForm(UserCreationForm):
class meta:
fields
class onetoonefieldForm(NormalUserForm):
class meta:
add_field += (number)
tried playing with required_fields, but again... number is unique
tried making two abstractUsers... permissions errors
thought about just making it non-unique and just checking on db insert that it's unique, but that seemed like a risk to the database, when it's vital it's unique.
Thank you for listening:)
Have a great day
Do I have to manually make two different user classes along with the permissions, authentication etc.? or is there separate user models for admin/user in django?
Django uses one built in User model and distinguishes three types of users using the attributes is_staff and is_superuser.
Normal user: is_staff=False, is_superuser=False
Staff user (can access the admin interface): is_staff=True
Super user (can do everything): is_superuser=True
If the default user model does not work for you, you can extend it or replace it.
Having the user decide their primary key, is not the intended default. The primary key is usually decided by the database, which also handles the uniqueness. If you would like to assign a unique number to each user, such as a customer number, I suppose it is easiest to extend the user model with a user profile.

Django Auth User Model Set different field name for password

I recently look into Django framework and plan to migrate my old system into it. Therefore, there is legacy mysql database that I need to follow. Is there anyway to change the field name of password of Django User Model? such as "pwd" or "password2".
I got research the Django document, only able to find out changing the username field
https://docs.djangoproject.com/en/2.2/topics/auth/customizing/#django.contrib.auth.models.CustomUser.USERNAME_FIELD
I think you can create a new class that inherits from user model and set the password field to be whatever you like.
Something like:
class MyUser(AbstractBaseUser):
...
password = models.CharField(max_length=100, db_column='custom_name')
...

Should I use the default users model in django 1.11 for my project

Actually, I'm working on a project where I need to save some details like name, username, password, age, gender etc of every user.
In that website, any user can login to their account, edit information.
So should I use the default users model or create a new model
I suggest you subclass AbstractUser. This option is suitable if you're fine with Django's User fields, but need extra fields. Django documentation also recommends to do this anyway.
If you’re starting a new project, it’s highly recommended to set up a
custom user model, even if the default User model is sufficient for
you. This model behaves identically to the default user model, but
you’ll be able to customize it in the future if the need arises:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass or additional fields here ...
You also have to point to this model before creating or running any migration in the settings:
AUTH_USER_MODEL = 'yourapp.User'
Default user model in Django save some limited fields about one user. fields are
first_name, last_name, email, password, groups, user_permissions, is_staff, is_active, is_superuser, last_login, date_joined
If you want to save other information of user like birthday, expertise, gender you have to write userprofile model which must be linked one to one with user.
Example:
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.OnetoOneField(User)
birthday = models.DateTimeField(default=datetime.datetime.now)
skills = models.CharField(max_length=128)
Actually, If you want to create a custom user model for user, It's mentioned in the Django's Official documentation. For achieving that you have to first inherit your custom user model with AbstractUser class and then pointing that custom user in your settings file by mentioning
AUTH_USER_MODEL = 'mycustom_user_app.MyCustomUser'.
Now django internally knows which model is the User model for the project, and you can access all model managers(e.g. create_user, etc. ) for your custom user. In that way you can use the current models fields and also can add more fields into it. That's the legit way to go with and to customize your User Model as mentioned in the documentation

In Django, is there a way to show the admin for a model under a different app?

I've extended the standard User with a Profile model using a one-to-one relationship:
class Profile(models.Model):
user = models.OneToOneField(User, primary_key=True, editable=False)
# Additional user information fields
This is in an app called account_custom. The issue is that in the admin site, I would like this model to show up along with User under "Authentication and Authorization".
I was able to make this show up in the right place in the admin by setting Meta.app_label:
class Profile(models.Model):
class Meta:
app_label = 'auth'
db_table = 'account_custom_profile'
I set Meta.db_table so this uses the existing database table, and everything seems to function properly.
The problem is that Django wants to generate migrations for this, one in account_custom to delete the table and one in auth to create it again. I'm guessing this would either fail or wipe out the data depending on the order the migrations are run, but the deeper problem is that it's trying to create a migration in auth which isn't part of my code base.
Is there a way around this, or is there some better way to control where a ModelAdmin shows up in the admin site?

When to use the Custom User Model in Django 1.5

I have a question regarding the custom user model in Django 1.5
So right now the default user model looks just fine to me, I just need to add a few other variables such as gender,location and birthday so that users can fill up those variables after they have successfully registered and activated their account.
So, what is the best way to implement this scenario?
Do I have to create a new app called Profile and inherit AbstractBaseUser? and add my custom variable to models.py? Any good example for me to follow?
thank you in advance
You want to extend your user model to the AbstractUser and add your additional fields. AbstractUser inherits all of the standard user profile fields, whereas AbstractBaseUser starts you from scratch without any of those fields.
It's hard to define best practices this close to the release, but it seems that unless you need to drastically redefine the User model, then you should use AbstractUser where possible.
Here are the docs for extending the User model using AbstractUser
Your models.py would then look something like this:
class MyUser(AbstractUser):
gender = models.DateField()
location = models.CharField()
birthday = models.CharField()
MyUser will then have the standard email, password, username, etc fields that come with the User model, and your three additional fields above.
Then you need to add the AUTH_USER_MODEL to your settings.py:
AUTH_USER_MODEL = 'myapp.MyUser'