Reputation: 153
I have a Profile
model that extends the user model like so,
class Profile(User):
user = models.OneToOneField(User, parent_link=True, on_delete=models.CASCADE)
slug = models.SlugField(unique=True, blank=True)
def save(self, *args, **kwargs):
print('self.username')
print(self.username)
self.slug = self.username
super(Profile, self).save(*args, **kwargs)
I am trying to create a slug field for my model , so I override the save method to include the slug as the username. The thing is, when I create a new user with the command createsuperuser
and print out the username as you can see in the code, it doesn't show anything - it doesn't show the provided username. Could this be the reason why I am having this problem ? And if so, how can I fix it?
Upvotes: 2
Views: 596
Reputation: 303
Profile cannot inherit User but instead should inherit Model. And, for the creation of User to be able to create a corresponding row in a different table (Profile) and set the slug will involve the use of signals.
Upvotes: 1
Reputation: 303
You are overriding the save method correctly. You need to do more when you use the createsuperuser
command.
from django.utils.text import slugify
from django.contrib.auth.models import UserManager
class CustomUserManager(UserManager):
def _create_user(self, username, email, password, **extra_fields):
username_slug = slugify(username)
extra_fields.setdefault('slug', username_slug)
super()._create_user(username, email, password, **extra_fields)
class Profile(User):
user = models.OneToOneField(User, parent_link=True, on_delete=models.CASCADE)
slug = models.SlugField(unique=True, blank=True)
def save(self, *args, **kwargs):
print('self.username')
print(self.username)
self.slug = slugify(self.username)
super().save(*args, **kwargs)
objects = CustomUserManager()
Upvotes: 0
Reputation: 1183
If you're sure you don't want to have your user's profile data in a separate model with a OneToOneField
back to Django's default User
, then you should probably subclass AbstractUser
and not User
, as specified in the docs.
https://docs.djangoproject.com/en/2.2/topics/auth/customizing/#substituting-a-custom-user-model
Consider this part :
If you’re entirely happy with Django’s User model and you just want to add some additional profile information, you could simply subclass django.contrib.auth.models.AbstractUser and add your custom profile field [...]
(from https://docs.djangoproject.com/en/2.2/topics/auth/customizing/#extending-django-s-default-user)
Then you'd go like this:
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import UserManager
from django.utils.text import slugify
from django.db import models
class User(AbstractUser):
slug = models.SlugField(unique=True, blank=True)
objects = UserManager()
def save(self, *args, **kwargs):
print('self.username')
print(self.username)
self.slug = slugify(self.username)
super().save(*args, **kwargs)
Then, define settings.AUTH_USER_MODEL
,
AUTH_USER_MODEL = "myapp.User" # also, add 'myapp' to INSTALLED_APPS
Remember: you'll need to reference your User model like this (and this is how you should do it anyway, whether you customized that model or not):
from django.contrib.auth import get_user_model
User = get_user_model()
Upvotes: 2