Hello Django professionals!
I am trying to create a base accounts app that i can reuse for different projects, so i don’t have to retype all accounts app and everything that goes with it, each time i create a new project. I am trying to escape from WordPress so it is a big challange, but i love the decision i made.
So, in the accounts app i have created a custom user.
Everything that i have learned so far, is working.
- registration
- login
- logout
- password change
- password reset
Now i am trying to create types of users. As i understand, it is recommended that we use only one custom user and have different types of that user.
For us, those are:
- Admin
- Company owner
- Company employees
- Customers
Here is my accounts app models, for Custom User
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
# NEW FOR THE ROLES
class Types(models.TextChoices):
ADMIN = "ADMIN", "Admin"
OWNER = "OWNER", "Owner"
EMPLOYEE = "EMPLOYEE", "Employee"
CUSTOMER = "CUSTOMER", "Customer"
type = models.CharField(
max_length=20, choices=Types.choices, default=Types.ADMIN
)
email = models.EmailField(unique=True, max_length=50)
username = models.CharField(unique=True, max_length=20)
note = models.TextField(max_length=200, null=True, blank=True)
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["username"]
def __str__(self):
return self.email
So i have defined a custom user, imported it into Settings.py and everything is working.
The problem occures when i want to create Types of users. I am having troubles finding the content online that i could learn from.
Okay so this is what i have tried:
# custom model managers for user roles
class OwnerManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(type=User.Types.OWNER)
class Owner(User):
objects = OwnerManager()
class Meta:
proxy = True
def save(self, *args, **kwargs):
if not self.pk:
self.type = User.Types.OWNER
return super().save(*args, **kwargs)
Then i went into views.py, created a sepparate view for registering the owner, it is this one:
def register_view_owner(request):
if request.method == "POST":
form = UserRegisterForm(request.POST)
if form.is_valid():
# save the user but deactivate him
user = form.save(commit=False)
user.type = User.Types.OWNER
form.save()
messages.success(request, "Owner is created. login now.")
return redirect("accounts:login_view")
else:
form = UserRegisterForm()
context = {
"form": form,
}
return render(request, "accounts/register-owner.html", context)
After that, i have created a sepparate url register-owner and the html page for it.
When i submit the form on that page, i do get my owner created, because i used user.type = User.Types.OWNER in the view.
I did the same for employees and customers, everhing is working. I also created a dashboard page and put in:
{% if request.user.type == 'ADMIN' %}
You are admin
{% elif request.user.type == 'OWNER' %}
You are the owner, you can create new employees and edit orders.
{% elif request.user.type == 'CUSTOMER' %}
You are a customer, you can see your orders.
{% endif %}
I did that just to test, if those different types of users will see their corresponding info, and it works.
So now the problem.
How do i assign additional data for different types of users?
For this owner, we need company name, address, url…
I tried to create a Class OwnerProfile and tried a signal, but that is what i can’t find the answer for
@receiver(post_save, sender=Owner)
def create_user_profile(sender, instance, created, **kwargs):
if created and instance.type == 'OWNER':
OwnerProfile.objects.create(user=instance)
# Owner Profile for more data for the owner
class OwnerProfile(models.Model):
# relation to Owner
user = models.OneToOneField(User, on_delete=models.CASCADE)
owner_first_name = models.CharField(max_length=20)
company_name = models.CharField(max_length=50, default='Adidas')
company_description = models.TextField(blank=True, null=True)
def __str__(self):
return self.owner_first_name
That is that in a nutshell
I hope somebody can help me, thank you and best regards from Serbia