Chau Loi
Chau Loi

Reputation: 1225

No username attribute of model error, even already have objects = UserManager()?

Here is my model in the user app

from django.db import models 
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin

class UserTable(AbstractBaseUser, PermissionsMixin):
    USERNAME_FIELD='email'
    objects = UserManager()
    email = models.EmailField(max_length=255, unique=True)
    name = models.CharField(max_length=255)
    phone = models.CharField(max_length=255, default=None)
    is_active = models.BooleanField(default=False)

Here is my admin.py inside the user app.

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import UserTable

admin.site.register(UserTable, UserAdmin)

I also included in my settings.py

INSTALLED_APPS = [
    ....
    'user.apps.UserConfig',
    ....
]

This is the error when I run python manage.py migrate

(admin.E033) The value of 'ordering[0]' refers to 'username', which is not an attribute of 'user.UserTable'.
The value of 'list_display[0]' refers to 'username', which is not a callable, an attribute of 'UserAdmin', or an attribute or method on 'user.UserTable'. 

I dont know why, I thought when I set objects = UserManager() fields like username, first_name, last_name is setted up. I also user USERNAME_FIELD to set email replacing the username primary key.

Upvotes: 1

Views: 225

Answers (2)

Brian Destura
Brian Destura

Reputation: 12068

The problem is because you are inheriting from AbstractBaseUser (which does not come with a username field):

class AbstractBaseUser(models.Model):
    password = models.CharField(_('password'), max_length=128)
    last_login = models.DateTimeField(_('last login'), blank=True, null=True)
    ... # No definition for usename in this class

and then using UserAdmin (which requires username as field) as your admin:

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    ...
    # The admin needs the username field as described by ordering
    # But your custom user model doesn't have it
    ordering = ('username',)

There are a number of ways to fix this, but one way is to define your own model admin for your custom user:

from django.contrib import admin

class MyAdmin(admin.ModelAdmin):
    pass


admin.site.register(UserTable, MyAdmin)

Upvotes: 1

Mohamed Hamza
Mohamed Hamza

Reputation: 985

You are supposed to write ur own UserManager

from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.contrib.auth.models import PermissionsMixin 

class UserManager(BaseUserManager):

  def create_user(self, email, password, **extra_fields):
     if not email:
        raise ValueError('User must have an email address')
        
    user = self.model(
        email=self.normalize_email(email),
         **extra_fields
    )
    user.set_password(password)
    user.save()
    return user

 def create_superuser(self, email, password, **extra_fields):
     user = self.create_user(
        email,
        password,
        **extra_fields
    )
    return user

Just a small comment in UserTable model, make

is_active = models.BooleanField(default=True) To be able to login

And in settings.py file add

AUTH_USER_MODEL = 'user.UserTable'

Edit

I noticed that you are calling AbstractBaseUser, BaseUserManager in a wrong way

from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
from django.contrib.auth.models import PermissionsMixin

Try it out and told me if there is any problem!

Upvotes: 2

Related Questions