Skip to content

Instantly share code, notes, and snippets.

@ra0x3
Last active March 6, 2020 17:21
Show Gist options
  • Save ra0x3/ccb571ffefdee9588d5b146ae3dc3040 to your computer and use it in GitHub Desktop.
Save ra0x3/ccb571ffefdee9588d5b146ae3dc3040 to your computer and use it in GitHub Desktop.
A sample model manager demonstrating how joins work
from peewee_extensions import PeeweeExtensions
class BaseManager:
def __init__(self, name):
self.model_name = name
self.exts = PeeweeExtensions(self)
self.model = BaseManager.model_for(self.model_name)
self.relations = self.model._meta.relations
@staticmethod
def model_for(modelname):
return getattr(models, modelname)
@db_rollback() # a simple decorator to rollback operations that generate errors
def find(self, params):
params = self.exts.normalize_query_parts(params)
if self.exts.has_no_includes(params):
fields = self.exts.derive_fields(params)
clause = self.exts.and_filter(params.query)
results = self.model.select(*fields).where(clause).execute()
return results
join_exprs = []
join_models = [self.model] + [
BaseManager.model_for(name) for name in params.include
]
join_models = [self.model]
for name in params.include:
model = BaseManager.model_for(name)
if model._meta.relations.has_thru(self.model_name):
thru_name = model._meta.relations.thru_for(self.model_name)
thru = BaseManager.model_for(thru_name)
if not thru in join_models:
join_models.append(thru)
join_models.append(model)
clause = self.exts.and_filter(params.query)
query = self.model.select(*join_models).where(clause)
thrus_seen = set()
for name in params.include:
assoc = self.relations.data[name]
foreign_model = BaseManager.model_for(name)
if assoc.how == "direct":
query = query.join(foreign_model).switch(self.model)
else:
thru_model = BaseManager.model_for(assoc.relation.thru_model)
if not thru_model._meta.table_name in thrus_seen:
query = query.join(thru_model).where(
getattr(self.model, assoc.relation.native_key)
== getattr(thru_model, assoc.relation.thru_key)
)
thrus_seen.add(thru_model._meta.table_name)
query = query.join(foreign_model).switch(thru_model)
return query.execute()
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment