gault-millau/apps/utils/models.py

142 lines
3.9 KiB
Python

"""Utils app models."""
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.contrib.gis.db import models
from django.contrib.postgres.fields import JSONField
from django.contrib.postgres.fields.jsonb import KeyTextTransform
from django.utils import timezone
from django.utils.html import mark_safe
from django.utils.translation import ugettext_lazy as _
from easy_thumbnails.fields import ThumbnailerImageField
from utils.methods import image_path
class ProjectBaseMixin(models.Model):
"""Base mixin model."""
created = models.DateTimeField(default=timezone.now, editable=False,
verbose_name=_('Date created'))
modified = models.DateTimeField(auto_now=True,
verbose_name=_('Date updated'))
class Meta:
"""Meta class."""
abstract = True
class OAuthProjectMixin:
"""OAuth2 mixin for project GM"""
def get_source(self):
"""Method to get of platform"""
return NotImplemented
basemixin_fields = ['created', 'modified']
class BaseAttributes(ProjectBaseMixin):
created_by = models.ForeignKey(
'account.User', on_delete=models.SET_NULL, verbose_name=_('created by'),
null=True, related_name='%(class)s_records_created'
)
modified_by = models.ForeignKey(
'account.User', on_delete=models.SET_NULL, verbose_name=_('modified by'),
null=True, related_name='%(class)s_records_modified'
)
class Meta:
"""Meta class."""
abstract = True
class ImageMixin(models.Model):
"""Avatar model."""
THUMBNAIL_KEY = 'default'
image = ThumbnailerImageField(upload_to=image_path,
blank=True, null=True, default=None,
verbose_name=_('Image'))
class Meta:
"""Meta class."""
abstract = True
def get_image(self, key=None):
"""Get thumbnailed image file."""
return self.image[key or self.THUMBNAIL_KEY] if self.image else None
def get_image_url(self, key=None):
"""Get image thumbnail url."""
return self.get_image(key).url if self.image else None
def image_tag(self):
"""Admin preview tag."""
if self.image:
return mark_safe('<img src="%s" />' % self.get_image_url())
else:
return None
image_tag.short_description = _('Image')
image_tag.allow_tags = True
class PlatformMixin(models.Model):
"""Platforms"""
MOBILE = 0
WEB = 1
SOURCES = (
(MOBILE, _('Mobile')),
(WEB, _('Web')),
)
source = models.PositiveSmallIntegerField(choices=SOURCES, default=MOBILE,
verbose_name=_('Source'))
class Meta:
"""Meta class"""
abstract = True
class LocaleManagerMixin(models.Manager):
"""Manager for locale"""
def annotate_localized_fields(self, locale):
"""Return queryset by locale"""
prefix = 'trans'
# Prepare fields to localization (only JSONField can be localized)
fields = [field.name for field in self.model._meta.fields if isinstance(field, JSONField)]
# Check filters to check if field has localization
filters = {f'{field}__has_key': locale for field in fields}
# Filter QuerySet by prepared filters
queryset = self.filter(**filters)
# Prepare field for annotator
localized_fields = {f'{field}_{prefix}': KeyTextTransform(f'{locale}', field) for field in fields}
# Annotate them
for _ in fields:
queryset = queryset.annotate(**localized_fields)
return queryset
class GMTokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
return (
str(user.pk) +
str(timestamp) +
str(user.is_active)
)
gm_token_generator = GMTokenGenerator()