Repository URL to install this package:
Version:
0.3.0a1 ▾
|
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',
)