Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A try of library for defering field in Django. This version is prepared with relationship (FK, ManyToMany etc) in mind. Inpired by https://github.com/mirumee/satchless/blob/master/satchless/util/models.py
from django.db import models
class DeferedField(object):
def __init__(self, cls, **kwargs):
'''When defining defered field, we declare it's type and properties'''
self.cls = cls
self.kwargs = kwargs
def construct(self, model_alias, **kwargs):
'''When fixing defered field we give it referenced model
and may update it's properties'''
self.kwargs.update(kwargs)
return self.cls(model_alias, **self.kwargs)
class DeferedForeignKey(DeferedField):
def __init__(self, **kwargs):
return super(DeferedField, self).__init__(models.ForeignKey, **kwargs)
class DeferedModel(models.Model):
class Meta:
abstract = True
@classmethod
def settle(cls, **kwargs):
new_fields = {}
# for every class in hierarchy
# ordered by python's method resoultion order
for c in reversed(cls.__mro__):
# inspect all fields of that class
for field_name, field in c.__dict__.iteritems():
# to find DeferedField instances
if isinstance(field, DeferedField):
if field_name in kwargs:
# and settle them
new_fields[field_name] = field.construct(
kwargs.pop(field_name))
else: # if field_name in kwargs:
# or raise error if implementation not given
# TODO fix error class
raise TypeError("Implementation of every field is "
"required - please profide implementation for %s" %
field_name)
if len(kwargs) > 0:
# if to many arguments given then probably some error
raise TypeError("Superficient keyword arguments to sette model")
# when all field are extracted set them for the class
for k, v in new_fields.iteritems():
setattr(c, k, v)
return cls
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment