Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
dj-kaos / utils / models.py
Size: Mime:
from __future__ import annotations

from django.db import models
from django.db.models.query_utils import RegisterLookupMixin


class CleanSaveModelMixin(models.Model):
    """
    Run `full_clean` before saving the model. Adding this mixin to your models makes sure the logic in clean is
    called in situations where Django doesn't call it by default (e.g. rest framework).
    """

    class Meta:
        abstract = True

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        self.full_clean()
        super().save(force_insert, force_update, using, update_fields)


class HasAutoFieldsModelMixin(models.Model):
    """
    Mixin for models that have fields that can be automatically set, for example by deriving from the value of other
    fields.
    """

    class Meta:
        abstract = True

    def set_auto_fields(self):
        """Override this method to set the fields that need to be automatically set"""

    def clean(self):
        self.set_auto_fields()
        super(HasAutoFieldsModelMixin, self).clean()

    def save(self, *args, **kwargs):
        self.set_auto_fields()
        super(HasAutoFieldsModelMixin, self).save(*args, **kwargs)


class CaseInsensitiveCharFieldMixin(RegisterLookupMixin):
    """
    Field mixin that uses case-insensitive lookup alternatives if they exist.

    Example:
        >>> class LowerCaseLookupCharField(CaseInsensitiveCharFieldMixin, models.CharField):
        >>>     pass
    """
    LOOKUP_CONVERSIONS = {
        'exact': 'iexact',
        'contains': 'icontains',
        'startswith': 'istartswith',
        'endswith': 'iendswith',
        'regex': 'iregex',
    }

    def get_lookup(self, lookup_name):
        converted = self.LOOKUP_CONVERSIONS.get(lookup_name, lookup_name)
        return super().get_lookup(converted)


class ToLowerCaseModelFieldMixin(models.Field):
    """
    Always save the field as lowercase
    """

    def to_python(self, value):
        return super(ToLowerCaseModelFieldMixin, self).to_python(value).lower()


class LowerCaseCharField(CaseInsensitiveCharFieldMixin, ToLowerCaseModelFieldMixin, models.CharField):
    """
    CharField that saves the values passed to it as lowercase.
    """


def generate_upload_path(instance, field_name, filename, get_id=lambda o: o.uuid):
    opts = instance._meta
    obj_id = get_id(instance)
    return f'/models/{opts.app_label}/{opts.model_name}/{obj_id}/{field_name}/{filename}'


__all__ = (
    'CleanSaveModelMixin',
    'HasAutoFieldsModelMixin',
    'CaseInsensitiveCharFieldMixin',
    'ToLowerCaseModelFieldMixin',
    'LowerCaseCharField',
    'generate_upload_path',
)