In general it depends on your architecture. Since you're using django, it's natural to walk the django path of fat models.
It's not clear from your example when you'd like to customer.add_bonus() but one approach you can take is modelling posh and sporty customers as different classes using inheritance. e.g.
proxy = True
proxy = True
Here we're using Django's proxy classes (https://docs.djangoproject.com/en/dev/topics/db/models/#proxy-models) to indicate that these customers are stored in the same database table, and only the behaviour is different.
Your comments below taken into consideration, I'd recommend not locking yourself into an architectural decision until you know more about your use cases. Continuing on your last comment, it sounds like you have behavior that's mostly split in two:
- Identifying a customer group
- Applying an action to the customers of the identified group.
I would probably model this as two different concepts, and stitch them together with use case-aligned services.
Identifying customer groups can be encapsulated using a custom model manager. (https://docs.djangoproject.com/en/dev/topics/db/managers/#custom-managers). E.g.
def made_purchase_in(self, timespan):
The actions could be modelled anyway you want, e.g. as methods on the Customer or as classes or functions that accepts customers as parameters:
def remind(self, email):
def __init__(self, customers):
self.customers = customers
for customer in self.customers:
And an example service:
customers = Customer.objects.made_purchase_in(timespan.LAST_30_DAYS)
reminder = RegularCustomerReminder(customers)