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 phonenumber_field.modelfields import PhoneNumberField from .helpers import profile_to_coords, upload_path class UserManager(BaseUserManager): use_in_migrations = True def _create_user(self, email, password, **extra_fields): values = [email] 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, **extra_fields ) user.set_password(password) user.save(using=self._db) return user def create_user(self, email, password=None, **extra_fields): return self._create_user(email, password, **extra_fields) def create_superuser(self, email, password=None, **extra_fields): extra_fields.setdefault('is_superuser', True) return self._create_user(email, 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' 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("Straße", max_length=64) city = models.CharField("Stadt", max_length=64) zip = models.CharField("PLZ", max_length=16) state = models.CharField("Bundesland", max_length=64, null=True, blank=True) country = CountryField("Staat") @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 PhoneMixin(models.Model): phone = PhoneNumberField("Mobiltelefon") class Meta: abstract = True class PersonMixin(models.Model): company = models.CharField("Firma", max_length=64, null=True, blank=True) vat_id = models.CharField("UID-Nummer", max_length=32, null=True, blank=True) first_name = models.CharField("Vorname", max_length=64) last_name = models.CharField("Nachname", max_length=64) class Meta: abstract = True class Profile(PersonMixin, AddressMixin, PhoneMixin): user = models.OneToOneField(User, models.CASCADE) verified = models.BooleanField(default=False) enabled = models.BooleanField(default=True) @property def full_name(self): name = " ".join([self.first_name, self.last_name]) if self.company: name += f" ({self.company})" return name class Meta: abstract = True