coderboy
coderboy

Reputation: 759

how to automatically set a superuser on creation a user type

I am using making use of some user_types in my application which are is_admin and is_landlord. I want it that whenever a user is created using the python manage.py createsuperuser. he is automatically assigned is_admin.

models.py

class UserManager(BaseUserManager):

    def _create_user(self, email, password, is_staff, is_superuser, **extra_fields):
        if not email:
            raise ValueError('Users must have an email address')
        now = datetime.datetime.now(pytz.utc)
        email = self.normalize_email(email)
        user = self.model(
            email=email,
            is_staff=is_staff,
            is_active=True,
            is_superuser=is_superuser,
            last_login=now,
            date_joined=now,
            **extra_fields
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email=None, password=None, **extra_fields):
        return self._create_user(email, password, False, False, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        user = self._create_user(email, password, True, True, **extra_fields)
        user.save(using=self._db)
        return user

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)

    # CUSTOM USER FIELDS
    name = models.CharField(max_length=30, blank=True, null=True)
    telephone = models.IntegerField(blank=True, null=True)

    USERNAME_FIELD = 'email'
    EMAIL_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager()

    def get_absolute_url(self):
        return "/users/%i/" % (self.pk)
        
    def get_email(self):
        return self.email

class user_type(models.Model):
    is_admin = models.BooleanField(default=False)
    is_landlord = models.BooleanField(default=False)
    user = models.OneToOneField(User, on_delete=models.CASCADE)

    def __str__(self):
        if self.is_landlord == True:
            return User.get_email(self.user) + " - is_landlord"
        else:
            return User.get_email(self.user) + " - is_admin"

Note: I want a superuser created to automatically have the is_admin status

Upvotes: 0

Views: 174

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477190

You can automatically construct a user_type model in the create_superuser function:

class UserManager(BaseUserManager):
    
    # …
    
    def create_superuser(self, email, password, **extra_fields):
        user = self._create_user(email, password, True, True, **extra_fields)
        user.save(using=self._db)
        user_type.objects.update_or_create(
            user=user,
            defaults={
                'is_admin': True
            }
        )
        return user

It is however not clear to my why you use a user_type class, and not just add extra fields to your User model. This will make it more efficient since these will be fetched in the same query when you fetc the logged in user. It is also more convenient to just access an .is_landlord attribute from the user model.


Note: Models in Django are written in PerlCase, not snake_case, so you might want to rename the model from user_type to UserType.

Upvotes: 1

coderboy
coderboy

Reputation: 759

So I have tried a method that works not so efficiently but manageably.

What I do is a simple trick.

views.py

def Dashboard(request, pk):
    
        user = User.objects.get(id=request.user.pk)
        landlord = user.is_staff & user.is_active
        if not landlord:
            reservations = Tables.objects.all()
            available_ = Tables.objects.filter(status="available")
            unavailable_ = Tables.objects.filter(status="unavailable")
            bar_owners_ = user_type.objects.filter(is_landlord=True)
            context = {"reservations":reservations, "available_":available_, "unavailable_":unavailable_, "bar_owners_":bar_owners_}
            return render(request, "dashboard/super/admin/dashboard.html", context)
        else:
            """Admin dashboard view."""
            user = User.objects.get(pk=pk)
            reservations = Tables.objects.filter(bar__user_id=user.id)
            available =Tables.objects.filter(bar__user_id=user.id, status="available")
            unavailable =Tables.objects.filter(bar__user_id=user.id, status="unavailable")

            context = {"reservations":reservations, "available":available, "unavailable":unavailable}

            return render(request, "dashboard/super/landlord/dashboard.html", context)

So I let Django know that if a user is active or has the is_active set to true only then they should have access to the dashboard else they wouldn't have access to it.

Upvotes: 0

Related Questions