from django.contrib.gis.db import models from django.contrib.gis.geos import Point from django.contrib.auth.models import AbstractBaseUser, BaseUserManager from django.contrib.auth import get_user_model from django.utils import timezone from django_countries.fields import CountryField from .helpers import profile_to_coords, upload_path class UserManager(BaseUserManager): use_in_migrations = True def _create_user(self, email, display_name, password, **extra_fields): values = [email, display_name] field_value_map = dict(zip(self.model.REQUIRED_FIELDS, values)) for field_name, value in field_value_map.items(): if not value: raise ValueError('The {} value must be set'.format(field_name)) email = self.normalize_email(email) user = self.model( email=email, display_name=display_name, **extra_fields ) user.set_password(password) user.save(using=self._db) return user def create_user(self, email, display_name, password=None, **extra_fields): return self._create_user(email, display_name, password, **extra_fields) def create_superuser(self, email, display_name, password=None, **extra_fields): extra_fields.setdefault('is_superuser', True) return self._create_user(email, display_name, password, **extra_fields) class User(AbstractBaseUser): email = models.EmailField(unique=True) is_active = models.BooleanField(default=True) date_joined = models.DateTimeField(default=timezone.now) last_login = models.DateTimeField(null=True) is_superuser = models.BooleanField(default=False) objects = UserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['display_name'] def get_full_name(self): return self.email def get_short_name(self): return self.email def has_permission(self, *args, **kwargs): return self.is_superuser @property def is_staff(self): return self.is_superuser has_module_perms = has_permission has_perm = has_permission class AddressMixin(models.Model): street = models.CharField(max_length=64) city = models.CharField(max_length=64) zip = models.CharField(max_length=16) state = models.CharField(max_length=64, null=True, blank=True) country = CountryField() @property def full_address(self): return f"{self.street}, {self.city}, {self.zip}, {self.state}, {self.country}" class Meta: abstract = True class LocationMixin(AddressMixin): coords = models.PointField() def save(self, *args, **kwargs): if not self.coords: lat, lon = profile_to_coords(self) self.coords = Point(lon, lat) super().save(*args, **kwargs) class Meta: abstract = True class ImageMixin(models.Model): image = models.ImageField(upload_to=upload_path, null=True, blank=True) class Meta: abstract = True class Profile(AddressMixin): user = models.OneToOneField(User, models.CASCADE) company = models.CharField(max_length=64, null=True, blank=True) vat_id = models.CharField(max_length=32, null=True, blank=True) first_name = models.CharField(max_length=64) last_name = models.CharField(max_length=64) verified = models.BooleanField(default=False) enabled = models.BooleanField(default=True) @property def full_name(self): if self.company: return self.company else: return " ".join([self.first_name, self.last_name]) class Meta: abstract = True