Reputation: 2122
I am using AbstractBaseUser
for that i have created a managers.py
for creating superuser
.
Everything is working except these line in managers.py. Even i tried to print(user.id)
before user.save(using=self._db)
it is printing None
user.save(using=self._db)
user.created_by_id = user.id
user.updated_by_id = user.id
user.save()
I have also used commit=False
in user.save(using=self._db, commit=False)
still it is giving error. See the errors at bottom.
In my models.py i have tweo field created_by
& updated_by
which should should not be null. Thats why i am saving in Managers.py which is creating all this error.
How can i solve this issue. Is there better approach. This condition is only required for creating superuser.
Models.py
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(_('first name'), max_length=30, blank=True)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
is_active = models.BooleanField(_('is user active'), default=True)
profile_image = models.ImageField(default='user-avatar.png', upload_to='users/', null=True, blank=True)
is_staff = models.BooleanField(_('staff'), default=True)
role = models.ForeignKey(Role, on_delete=models.CASCADE)
phone_number = models.CharField(max_length=30, blank=True, null=True)
address = models.CharField(max_length=100, blank=True, null=True)
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, related_name='user_created_by')
created_on = models.DateTimeField(_('user created on'), auto_now_add=True)
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, related_name='user_updated_by')
updated_on = models.DateTimeField(_('user updated on'), auto_now=True)
Managers.py
class UserManager(BaseUserManager):
use_in_migrations = True
def _create_user(self, email, password, **extra_fields):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError('The given email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.role_id = 1
user.first_name = "Super"
user.last_name = "Admin"
user.save(using=self._db)
user.created_by_id = user.id
user.updated_by_id = user.id
user.save()
return user
def create_user(self, email, password=None, **extra_fields):
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password, **extra_fields)
Error - for commit=False
super().save(*args, **kwargs)
TypeError: save() got an unexpected keyword argument 'commit'
Error - Without Commit False
raise utils.IntegrityError(*tuple(e.args))
django.db.utils.IntegrityError: (1048, "Column 'created_by_id' cannot be null")
Upvotes: 0
Views: 345
Reputation: 51978
commit=False
works for ModelForms. It does not work for model instances. As the error said in your question, there is no keyword argument named commit
exists in save method.
Also, before saving the user object, it can't produce any primary key. I would recommend to make created_by
null able. So that you can avoid integrity error.
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, related_name='user_created_by', null=True, default=None)
updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, related_name='user_updated_by', null=True, default=None)
Still, if you want to enforce this restriction, then you can do that in forms or serializer or override the save method as well in the User
model.
For example:
class User(...):
...
def save(self, *args, **kwargs):
if not self.is_superuser:
if not self.created_by or not self.updated_by:
raise Exception("Add these fields") # can be custom exception
super(User, self).save(*args, **kwargs)
Upvotes: 1