Reputation: 3915
I am designing a contact relationship application that needs to store contacts in groups. Basically I have 7 "group types" (simplified it to 3 for my image), each group type shares the same fields so I thought that it would make sense to use an abstract "group", and let all group types inherit the methods from this abstract group.
So this is basically the idea:
However, this approach results in a couple of unexpected difficulties. For example:
I am not able to use a foreignkey of an abstract class, so if I would want to model a relationship between a group and a contact, I have to use the following approach:
limit = (models.Q(app_label='groups', model="Group type A") |
models.Q(app_label='groups', model="Group type B") |
models.Q(app_label='groups', model="Group type C")
)
group_type = models.ForeignKey(ContentType, limit_choices_to=limit)
group_id = models.PositiveIntegerField()
group = GenericForeignKey('group_type', 'group_id')
This seems quite hacky, and with this approach I am forced to do some hard coding as well. I am not able to call all groups with a simple query, maybe a new group will be added in the future.
Is there a better approach to model a relationship like this? Am I using the abstract class completely wrong?
Edit: some extra explanation in response to the questions. A user is connected to a group with another object called "WorkRelation", because there is some extra data that is relevant when assigning a user to a group (for example his function).
I initially went for an abstract class because I thought that this would give me the flexibility to get all Group types be just calling Group.objects.all(). If I would use a base model, the groups aren't connected and I will also have to hard-code all group names.
Upvotes: 0
Views: 139
Reputation: 5554
Since your child models do not have additional fields, you can make them proxy models of the base group model. Proxy models do not create new database tables, they just allow having different programmatic interfaces over the same table.
You could then define your ForeignKey
to the base group model:
group = ForeignKey(BaseGroup)
Use django-polymodels or a similar app to have the groups casted to the right type when queried.
More on model inheritance in the doc.
Upvotes: 2
Reputation: 25539
Why don't use solid base model instead of abstract model? Then you just put contacts
as either ForeignKey
or ManyToMany
to the base model.
Upvotes: 0