4👍
✅
There is no generic answer to this, just considerations. The decision depends on the business logic you need to implement with this solution.
Two Columns
order.discount = ForeignKey(Discount, null=True)
order.social_discount = ForeignKey(SocialDiscount, null=True)
When checking in subsequent code:
if order.discount:
# do this based on Discount model
elif order.social_discount:
# do that based on SocialDiscount model
This is a solution in favor of two very different Discount behaviours.
Use this:
- if there are only those two and no more in the future,
- if you would call very different fields and methods on them (they have different business logic surrounding them).
Non-Abstract Parent
# renamed from AbstractDiscount to ParentDiscount for obvious reasons
order.discount = ForeignKey(ParentDiscount, null=True)
Subsequent code:
if order.discount:
# do things that apply to either discount
if isinstance(order.discount, 'Discount'):
# do things that only apply to Discount
elif isinstance(order.discount, 'SocialDiscount'):
# do things that only apply to SocialDiscount
Use this:
- if there might be more children of ParentDiscount in the future,
- if there is general business logic that applies to any type of ParentDiscount that would be shared between all children.
GenericForeignKey
Querying on GenericForeignKeys requires a bit of work. As @Andy remarked it is not directly supported, but you can of course query on content_type
and object_id
together. The __in
lookup won’t work unless you can rely on object_id
only.
It won’t work out of the box in forms. For the Django Admin, there might be some solution, though, see GenericForeignKey and Admin in Django.
Use this:
- if there might be more discounts of various types in the future (ask the product owner and make sure this is not just some far far away future),
- if there is general business logic that applies to any those types,
- if you don’t need a no-work quick Admin solution.
Source:stackexchange.com