0

I have a custom user setup like this:

class CustomUser(AbstractUser):
    pass

class Employee(CustomUser):
    user = models.OneToOneField(settings.AUTH_USER_MODEL)
    # other fields

In settings.py, I then add the following key:

AUTH_USER_MODEL = 'myapp.CustomUser'

I want to identify who logged in redirect them to appropriate views or urls.

In my account activation view, after the logging them in I redirect them to their appropriate page like this

if hasattr(user, 'employee'):
    return redirect('edit_employee', slug=user.employee.slug)
else:
    return redirect('index')

But this doesn't feel that right as I need to use this in other places like showing a different profile page link in the templates.

How do I better identify the regular user and employee in views and templates?

Animesh
  • 4,926
  • 14
  • 68
  • 110

2 Answers2

1

The idea of extending the User Model to create an Employee Model doesn't seem good to me. Instead of this, you can use Django Group Model and add the user to the employee group. In this way, you can easily check if a user belongs to Employee group or not.

Additionally, you can also use django permissions here. Assign your custom permissions to the employee group and restrict other users to view employee pages.

Mohammad Mustaqeem
  • 1,034
  • 5
  • 9
1

AFAIK you should not store different types of users in different tables. It will make your life pretty hard when defining relationships between other models and your users model.

My suggested approach would be having different profile models for different types of users and using a generic FK or some sort of other similar approaches to find out the user type and get their profile.

class CustomUser(AbstractUser):
    USER_TYPE_EMPLOYEE = 'employee'
    USER_TYPES = (
          (USER_TYPE_EMPLOYEE, _('Employee')),
    )

    user_type = models.CharField(max_length=max(map(len, map(operator.itemgetter(0), CustomUser.USER_TYPES))), choices=CustomUser.USER_TPYES)

    @property
    def profile_model(self):
         return {
              USER_TYPE_EMPLOYEE: EmployeeProfile
         }[self.user_type]

    @property
    def profile(self):
         return self.profile_model.objects.get_or_create(user_id=self.pk)


class EmployeeProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='employee_profile')
Mohammad Jafar Mashhadi
  • 4,102
  • 3
  • 29
  • 49
  • I admit it took me sometime to understand your approach. I am willing to go for this, but could you please point me toward a full solution with this approach? – Animesh Oct 13 '17 at 12:44
  • 1
    @Animesh The code I provided is a replacement for using a generic FK and is fully functional. If you want ti add new profile models, you should 1. make a new model like `EmployeeProfile` above, 2. Add the new user type in `USER_TYPES` 3. Add an Item in the dictionary returned by `profile_model` method to return your new profile model. – Mohammad Jafar Mashhadi Oct 16 '17 at 06:39
  • Thanks for direction, I will look into this. – Animesh Oct 17 '17 at 13:44