Source code for model_path_converter

# -*- coding: utf-8 -*-
import re
from django.urls import register_converter
from django.urls.converters import get_converter, IntConverter

__author__ = """Daniel Hepper"""
__email__ = 'daniel@consideratecode.com'
__version__ = '0.1.0'


[docs]def camel_to_snake(s): camel_to_snake_regex = r'((?<=[a-z0-9])[A-Z]|(?!^)(?<!_)[A-Z](?=[a-z]))'
return re.sub(camel_to_snake_regex, r'_\1', s).lower()
[docs]def snake_to_camel(s): snake_to_camel_regex = r"(?:^|_)(.)"
return re.sub(snake_to_camel_regex, lambda m: m.group(1).upper(), s)
[docs]class ModelConverterMixin:
[docs] def get_queryset(self): if self.queryset: return self.queryset.all()
return self.model.objects.all()
[docs] def to_python(self, value): try: return self.get_queryset().get(**{self.field: super().to_python(value)}) except self.model.DoesNotExist:
raise ValueError
[docs] def to_url(self, obj):
return super().to_url(getattr(obj, self.field))
[docs]def register_model_converter(model, name=None, field='pk', base=IntConverter, queryset=None): """ Registers a custom path converter for a model. :param model: a Django model :param str name: name to register the converter as :param str field: name of the lookup field :param base: base path converter, either by name or as class (optional, defaults to `django.urls.converter.IntConverter`) :param queryset: a custom querset to use (optional, defaults to `model.objects.all()`) """ if name is None: name = camel_to_snake(model.__name__) converter_name = '{}Converter'.format(model.__name__) else: converter_name = '{}Converter'.format(snake_to_camel(name)) if isinstance(base, str): base = get_converter(base).__class__ converter_class = type( converter_name, (ModelConverterMixin, base,), {'model': model, 'field': field, 'queryset': queryset} )
register_converter(converter_class, name)