from django.db import models # Create your models here. # custom user model from django.db import models # import classes needed for custom user model from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager from main_project import settings # set up logger import logging import os logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # create file handler and set level to INFO log_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'user_logs.txt') fh = logging.FileHandler(log_file) fh.setLevel(logging.INFO) # create formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) logger.addHandler(fh) # custom user manager class Users_CustomUserManager(BaseUserManager): # called when creating user through drf terminal and frontend # only pass in req params, all other unrequired params like # first/lastname, favorite color, etc. will be held in **extra_fields param def create_user(self, email, username, password, **extra_fields): if not email: raise ValueError("Email must be provided") if not username: raise ValueError("Username must be provided") user = Users( email = self.normalize_email(email), username = username, **extra_fields ) user.set_password(password) user.save(using=self._db) return user # called when creating superuser through terminal drf def create_superuser(self, email, username, password, **extra_fields): extra_fields.setdefault('is_staff',True) extra_fields.setdefault('is_superuser',True) if extra_fields.get('is_staff') is not True: raise ValueError('Superuser must have is_staff=True.') if extra_fields.get('is_superuser') is not True: raise ValueError('Superuser must have is_superuser=True.') return self.create_user(email, username, password, **extra_fields) # Custom User Model class Users(AbstractBaseUser, PermissionsMixin): # ; define fields you want to be included in User Model, can be updated and changed later # this is the power of implementing a custom user model # allow authentication by username or email, or whatever else! email = models.EmailField(db_index=True, max_length=100, unique=True) username = models.CharField(db_index=True, max_length=64, unique=True) # non-req'd fields user_first_name = models.CharField(max_length=50, blank=True, null=True) user_last_name = models.CharField(max_length=50, blank=True, null=True) # will be uploaded to /media/ directory user_profile_pic = models.ImageField(upload_to='user_pfps', blank=True, null=True) # just for fun user_favorite_bible_verse = models.CharField(max_length=20, blank=True, null=True) date_user_added = models.DateTimeField(auto_now_add=True) # if user is allowed access to admin site. is_staff = models.BooleanField(default=False) # if user is currently active is_active = models.BooleanField(default=True) is_superuser = models.BooleanField(default=False) # connect user class to manager class objects = Users_CustomUserManager() # choose wisely, password resets will use this field # needs to have unique=True USERNAME_FIELD = 'username' # used by python manage.py createsuperuser and presumably drf for token authentication # should not contain the USERNAME_FIELD or password as these fields will always be prompted for. REQUIRED_FIELDS = ['user_first_name', 'user_last_name', 'email'] # this custom user model's name was clashing with Django's default user names, so adding these two # fields for groups and user_permissions is required groups = models.ManyToManyField( 'auth.Group', related_name='user_set_custom', related_query_name='user_custom', blank=True, help_text='The groups this user belongs to. A user will get all permissions ' 'granted to each of their groups.', verbose_name='groups', ) user_permissions = models.ManyToManyField( 'auth.Permission', related_name='user_set_custom', related_query_name='user_custom', blank=True, help_text='Specific permissions for this user.', verbose_name='user permissions', ) class Meta: db_table = 'users' # for admin page verbose_name_plural = "Users" def __str__(self): # return self.email return self.username @staticmethod def has_perm(perm, obj=None, **kwargs): return True @staticmethod def has_module_perms(app_label, **kwargs): return True # get user profile pic def get_profile_pic(self): if self.user_profile_pic: if settings.env('DEV_MODE') == 'True': return settings.env('DEV_DOMAIN') + self.user_profile_pic.url else: return settings.env('DOMAIN') + self.user_profile_pic.url return '' # create user obj for performing user actions # get_user_model defined in settings.py # has to be defined below since user model hasn't been installed/loaded yet from django.contrib.auth import get_user_model user_obj = get_user_model()