In my application a number of different kinds of Record
s can be mapped to a Person
. In my initial implementation, I made each record inherit from an abstract base class and used GenericRelation
s to manage the whole thing. The code is a bit complicated, but it works:
models.py
class Person(models.Model):
...
class PersonRecordMapping(models.Model):
person = models.ForeignKey(Person)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
class RecordParent(models.Model):
people = GenericRelation(PersonRecordMapping)
class Meta:
abstract = True
class RecordA(RecordParent):
w = ...
x = ...
class RecordB(RecordParent):
y = ...
z = ...
And so on. (As I tried to indicate, each type of Record
is quite different from the others, with very different fields on each model.)
As I built out the application around these models, I began to wonder if this approach would scale, as I will eventually have a number of RecordX
-type classes. I began to consider how to get all of the Record
s in one table with a column indicating which kind of Record
each one was, and eventually discovered the new-ish JSONField
. At first blush, it seemed to be exactly what I was looking for to simplify this whole thing.
class PersonRecordMapping(models.Model):
person = models.ForeignKey(Person)
record = models.ForeignKey(Record)
class Record(models.Model):
type = models.ForeignKey(RecordType) # New model to identify whether a RecordA, RecordB, &c.
data = JSONField()
All of this seemed well and good until I realized how much functionality I lost by turning model fields into JSON attributes, functionality that it is important given that the data in the JSON is user-inputted.
- I can't easily validate the data entry in the JSON. Apparently I could so something like
data = JSONField(validators=[something???])
, but from what I can tell this implementation doesn't lend itself to a case where thevalidator
depends on the value ofRecord.type
. - Even if I could figure that out, I lose the clean admin interface for individual fields. Yes, I guess I could make custom forms with custom save functions, but that seems fairly cumbersome.
So -- I'm looking for insight into what is the best architecture for this case, balancing performance without needlessly complicating the code base. Or, is there some other approach to this situation I'm not aware of?
(I know this isn't the ideal Stack Overflow question, but I hope evaluating these (or other) code examples against performance and maintainability makes this question answerable, not just discussable?)