I am using AbstractBaseUser and UserCreationForm with my Django app. When registering users through my app, the password gets saved in hash format and saved in the database. But when I try to do the same thing using Django admin site, the password gets saved in raw format.
You need to make sure that your model admin class knows how to hash passwords. According to the docs, if you are using subclassing AbstractBaseUser, then you might be able to extend UserAdmin.
Assuming your custom user model is called CustomUser, you could try the following.
from django.contrib.auth.admin import UserAdmin
class CustomUserAdmin(UserAdmin):
...
admin.site.register(CustomUser, CustomUserAdmin)
I guess the problem is that you inherited ModelAdmin instead of UserAdmin from django.contrib.auth.admin in your admin.py.
Sample code:
from django.contrib.auth.admin import UserAdmin
from .models import Employee
class EmployeeAdmin(UserAdmin):
pass
admin.site.register(Employee, EmployeeAdmin)
Related
I have to import the User model in a file and I was wondering if there is any difference between the auth.models.User and an abstract user in .models.User:
from django.contrib.auth.models import User
or
from .models import User
The first one from django.contrib.auth.models import User is the standard extension of AbstractUser with no additional fields. Whereas your from .models import User is your customised User model that should also inherit from AbstractUser but has customisation for your Django project.
You can see what django.contrib.auth.models does in the source code on GitHub.
I'm trying to manage my User table with django.contrib.admin
But during I add the User table in admin, I had an issue that doesn't appear in admin site.
Here is my code.
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
#admin.register(User)
class CustomUserAdmin(UserAdmin):
pass
assert admin.site.is_registered(User) # Fails here
And when I added the other custom model, it works.
Thanks
When you modify or implement the user model, you have to be aware of AUTH_USER_MODEL.
I changed AUTH_USER_MODEL in setting.py, and it starts to work.
Thanks.
I'm trying to create a custom user class and I'd like to know the best practice for implementing referencing the new user. After following the Django docs method of implementing the custom user as follows in models.py:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
And settings.py
AUTH_USER_MODEL = 'myapp.MyUser'
And admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User
admin.site.register(User, UserAdmin)
The Django docs say to use settings.AUTH_USER_MODEL in place of user specifically for ForeignKeys and OnetoOneField, but it's not clear about other instances.
My question is specific to how to refer to the custom user class in views.py. Before defining the user class I was using
from django.contrib.auth.models import User
But after defining a custom class this is no longer correct. I've seen boilerplate code use this method in the beginning of views.py:
from django.contrib.auth import get_user_model
User = get_user_model()
Is this the best practice for referencing the custom user? Or should I just be using settings.AUTH_USER_MODEL in place of where I previously had User?
Using settings.AUTH_USER_MODEL will load the user class lazily after all django apps are loaded. Calling get_user_model() on a module level when your app is initially loaded may result in that the user model app is not loaded and also circular imports.
Update: I read two specific questions:
How to correctly access the user model, contrib or custom.
Djangos get_user_model() is quite simply a call to django.apps get_model() using the settings.AUTH_USER_MODEL. If you are writing apps that might be reused in other projects with other user models, use the get_user_model call. Always. Then it doesn't matter what the user model is.
If you have created your own core.User model and is very confident that your code will only be used in this project, from core.models import User works as well.
When to use the string representation from settings instead of fetching the model.
The string representation will in the end usually call the same django.apps get_model() anyway. By giving a string instead of the class itself in Foreignkeys, OneToOneFields etc you simply don't require the model to be looked up during django app imports, where the user model may not yet be available. So using string representation is simply deferred loading of a model. The same goes for all models.
An also during djangos different major versions this behavior have changed, which is another topic. Notice that get_user_model() have been updated in Django 1.11 for import usage.
https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#referencing-the-user-model
you can go with get_user_model instead User
from django.contrib.auth import get_user_model
User = get_user_model()
get_user_model will Returns the User model that is active in this project.
if you modify(adding new field into it) default User table you need to use get_user_model it will return active User table.
BTW User will return native from django.contrib.auth.models
I am trying to inherit from AbstractUSer my models.py looks like:
class MyUser(AbstractUser):
created = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username',]
MyUser._meta.get_field_by_name('email')[0]._unique=True
now by declaring email as unique field and username as a required field my superuser is being created successfully and also is being authenticated properly but I am having a problem while creating any other user as if I am creating any user through my admin page its not being authenticated.It always returns
None
My admin.py:
from django.contrib import admin
from credilet.models import *
admin.site.register(MyUser)
What I am thinking is that the create_user is not being called properly as if I see in my admin page the password is not hashed so that means the create_user is not being called properly.Somebody please help through it or even if you have a proper documentation on abstractuser
not abstractbaseuser
so please refer that to me in the solutions.
Thanks
If you want to change the authentication system you have to use AbstractBaseUser,
look at this full example.
AbstractUser is ok to Extend Django’s default User.
I think you should add UserAdmin into admin.py for Myuser
if you does not add UserAdmin , password can't be hashed with django:
from django.contrib import admin
from credilet.models import *
from django.contrib.auth.admin import UserAdmin
admin.site.register(MyUser, UserAdmin) # add UserAdmin
When adding a new user to my Django application, I'd like to ensure that the administration page requires an administrator to include the "email" field.
I've tried tinkering with the UserAdminForm object, but I've come up empty thus far. Any tips?
You'll want to add something like this to one of your project's admin.py files:
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django.contrib.auth.models import Group, User
# Override username field require email address
class UserCreationForm2(UserCreationForm):
email = forms.CharField(max_length=75, required=True)
class UserChangeForm2(UserChangeForm):
email = forms.CharField(max_length=75, required=True)
class UserAdmin2(UserAdmin):
form = UserChangeForm2
add_form = UserCreationForm2
admin.site.unregister(User)
admin.site.register(User, UserAdmin2)
Essentially, make the email field required, unregister the built-in admin, and register a new admin with the override.