I'm trying to reduce clutter in my project's models.py and I decide to move out "utility" methods of some models.
The idea was to create a bunch of utility modules with classes and functions which will be used by model classes, but since there is no significant piece of code that doesn't use other models, it results in a circular dependence. E.g. in models.py
:
from myproject import parse_util
class Entry(models.Model):
text = models.TextField()
parser = parse_util.Parser(self)
def get_some_object():
return parser.parse_text()
class SomeModel(models.Model):
name = models.CharField(max_length=32, null=False, unique=True)
In parse_util.py
:
from myproject.models import SomeModel
class Parser():
def __init__(self, entry):
self.entry = entry
def parse_text(self):
# parsing self.entry.text
...
some_object = SomeModel.objects.get(name=parsed_value)
return some_object
I can avoid it by importing SomeModel
directly in the function, instead of doing it module-wide, or use get_model('myapp', 'SomeModel')
. But both of these don't look good.
After the whole day in thoughts I generalised the problem: what is the correct and pythonic way (if any) to move some code coupled with another code in the module out of that module?
That is if there is a module with classA
and classB
and there are lengthy methods of classB
, which use both classA
and classB
in some way, is there any good solution to cut down described module by splitting it into several models, but keeping entry points to classA
and classB
in place.
So you have the following hardcoded dependencies: Entry → Parser → SomeModel.
The way I would break the dependency is to make Parser
generic like this:
class Parser(object):
def __init__(self, entry, model):
self.entry = entry
self.model = model
def parse_text(self):
# parsing self.entry.text
...
some_object = self.model.objects.get(name=parsed_value)
return some_object
Now the hardcoded dependencies are just: Entry → Parser