Skip to content

Commit 212be10

Browse files
committed
Add typing to build_models.py
1 parent c4371b7 commit 212be10

File tree

2 files changed

+22
-15
lines changed

2 files changed

+22
-15
lines changed

specifyweb/specify/build_models.py

+16-14
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
from django.db import models
2+
from typing import Dict
23

34
from specifyweb.businessrules.exceptions import AbortSave
45
from . import model_extras
56
from .case_insensitive_bool import BooleanField, NullBooleanField
7+
from .datamodel import Datamodel, Table, Relationship, Field
68
from .deletion_rules import SPECIAL_DELETION_RULES, ADDITIONAL_DELETE_BLOCKERS
79

810
appname = __name__.split('.')[-2]
@@ -16,7 +18,7 @@
1618
'Collector': ('ordernumber',),
1719
}
1820

19-
def make_model(module, table, datamodel):
21+
def make_model(module: str, table: Table, datamodel: Datamodel) -> models.base.ModelBase:
2022
"""Returns a Django model class based on the
2123
definition of a Specify table.
2224
"""
@@ -64,18 +66,16 @@ def save(self, *args, **kwargs):
6466

6567
return model
6668

67-
def make_id_field(column):
69+
def make_id_field(column: str) -> models.AutoField:
6870
return models.AutoField(primary_key=True, db_column=column.lower())
6971

70-
def protect(collector, field, sub_objs, using):
72+
def protect(collector: models.deletion.Collector, field: models.Field, sub_objs: models.query.QuerySet, using:str):
7173
if hasattr(collector, 'delete_blockers'):
7274
collector.delete_blockers.append((field, sub_objs))
7375
else:
7476
models.PROTECT(collector, field, sub_objs, using)
7577

76-
77-
78-
def make_relationship(modelname, rel, datamodel):
78+
def make_relationship(modelname : str, rel: Relationship, datamodel: Datamodel) -> models.ForeignKey or models.OneToOneField:
7979
"""Return a Django relationship field for the given relationship definition.
8080
8181
modelname - name of the model this field will be part of
@@ -107,7 +107,7 @@ def make_relationship(modelname, rel, datamodel):
107107
else:
108108
on_delete = protect
109109

110-
def make_to_one(Field):
110+
def make_to_one(Field: type) -> models.ForeignKey or models.OneToOneField:
111111
"""Setup a field of the given 'Field' type which can be either
112112
ForeignKey (many-to-one) or OneToOneField.
113113
"""
@@ -134,7 +134,7 @@ class make_field(object):
134134
mechanism to factor out common aspects of Field configuration.
135135
"""
136136
@classmethod
137-
def get_field_class(cls, fld):
137+
def get_field_class(cls: type, fld) -> models.Field:
138138
"""Return the Django model field class to be used for
139139
the given field definition. Defaults to returning the
140140
'field_class' attribute of the class, but can be overridden
@@ -143,7 +143,7 @@ def get_field_class(cls, fld):
143143
return cls.field_class
144144

145145
@classmethod
146-
def make_args(cls, fld):
146+
def make_args(cls, fld: Field)-> Dict[str, str or bool]:
147147
"""Return a dict of arguments for the field constructor
148148
based on the XML definition. These are common arguements
149149
used by most field types.
@@ -154,7 +154,7 @@ def make_args(cls, fld):
154154
unique = fld.unique,
155155
null = not fld.required)
156156

157-
def __new__(cls, fld, fldargs):
157+
def __new__(cls, fld: Field, fldargs: Dict[str, bool]):
158158
"""Override the instance constructor to return configured instances
159159
of the appropriant Django model field for given parameters.
160160
@@ -206,7 +206,7 @@ class make_decimal_field(make_field):
206206
field_class = models.DecimalField
207207

208208
@classmethod
209-
def make_args(cls, fld):
209+
def make_args(cls, fld: Field):
210210
"""Augment the standard field options with those specific
211211
to Decimal fields.
212212
"""
@@ -224,15 +224,15 @@ def make_args(cls, fld):
224224
class make_boolean_field(make_field):
225225
"""A specialization of make_field for Boolean type fields."""
226226
@classmethod
227-
def get_field_class(cls, fld):
227+
def get_field_class(cls, fld: Field):
228228
"""Django differentiates between boolean fields which
229229
can contain nulls and those that cannot with different
230230
types.
231231
"""
232232
return BooleanField if fld.required else NullBooleanField
233233

234234
@classmethod
235-
def make_args(cls, fld):
235+
def make_args(cls, fld: Field):
236236
"""Make False the default as it was in Django 1.5"""
237237
args = super(make_boolean_field, cls).make_args(fld)
238238
if fld.required:
@@ -257,7 +257,9 @@ def make_args(cls, fld):
257257
'java.lang.Boolean': make_boolean_field,
258258
}
259259

260-
def build_models(module, datamodel):
260+
# Build the table information as Django models
261+
# See .models.py
262+
def build_models(module : str, datamodel: Datamodel):
261263
return { model.specify_model.tableId: model
262264
for table in datamodel.tables
263265
for model in [ make_model(module, table, datamodel) ]}

specifyweb/specify/models.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
"""
22
Sets up Django ORM with the Specify datamodel
33
"""
4+
from typing import Dict
5+
from django.db.models.base import ModelBase
46

57
from .build_models import build_models
68
from .check_versions import check_versions
79
from .datamodel import datamodel
810

9-
models_by_tableid = build_models(__name__, datamodel)
11+
# Returns a dictonary with the table's TableId as keys and the reated django models as values
12+
# The values (class paths) are constructed with this Module's name followed by the table name
13+
# Example: {7: <class 'specifyweb.specify.models.Accession'>}
14+
models_by_tableid : Dict[int, ModelBase] = build_models(__name__, datamodel)
1015

1116
# inject the model definitions into this module's namespace
1217
globals().update((model.__name__, model)

0 commit comments

Comments
 (0)