我的Django模型有一个pricing_plan
选择字段。有12个字段的值取决于pricing_plan
值。
class Organisation(models.Model):
PRICING_CHOICES = (
('basic', 'Basic'),
('team', 'Team'),
('super', 'Super')
)
# some fields...
pricing_plan = models.CharField(max_length=50, default='basic')
max_host_accounts = models.IntegerField(default=1)
max_admin_accounts = models.IntegerField(default=1)
max_guests = models.IntegerField(default=10)
# more fields whose value depends on pricing_plan value
对于每个不同的pricing_plan
,这些字段都会获得特定值。在代码中可以描述如下:
if pricing_plan == 'basic':
max_host_accounts = 1
max_admin_accounts = 1
max_guests = 10
...
elif pricing_plan == 'team':
max_host_accounts = 10
max_admin_accounts = 3
max_guests = 25
...
但是,未来可能会有更多的定价计划和更多选项,我担心if/elif/else
声明会很庞大且不易阅读。
在Django模型中实现它的最佳/惯用方法是什么?
Enum
类?
class BasicOrganisation(Organisation):
max_host_accounts = models.IntegerField(default=1)
max_admin_accounts = models.IntegerField(default=1)
max_guests = models.IntegerField(default=10)
class TeamOrganisation(Organisation):
max_host_accounts = models.IntegerField(default=10)
max_admin_accounts = models.IntegerField(default=3)
max_guests = models.IntegerField(default=25)
答案 0 :(得分:0)
我会这样做(我使用django-choices包进行伪Enum仿真):
from django.db import models
from djchoices import ChoiceItem, DjangoChoices
def get_max_admin_accounts(pricing_plan):
if pricing_plan == Organization.Pricing.BASIC:
return 1
# other code
class Organization(models.Model):
class Pricing(DjangoChoices):
BASIC = ChoiceItem('basic', 'Basic')
TEAM = ChoiceItem('team', 'Team')
SUPER = ChoiceItem('super', 'Super')
pricing_plan = models.CharField(max_length=50, default=Pricing.BASIC)
max_host_accounts = models.IntegerField()
max_admin_accounts = models.IntegerField()
max_guests = models.IntegerField()
def save(self, **kwargs):
if not self.max_admin_accounts:
self.max_admin_accounts = get_max_admin_accounts(self.pricing_plan)
# other fields filled
super().save(**kwargs)
答案 1 :(得分:0)
我会喜欢
class Organisation(models.Model):
PRICING_CHOICES = {
"basic": ("Basic", (1, 1, 10)),
"team": ("Team", (10, 3, 25)),
}
# some fields...
pricing_plan = models.CharField(choices=tuple([(i,j[0]) for i, j in PRICING_CHOICES.items()]), max_length=50, default='basic')
#other fields
def set_plan(self, max_host_accounts, max_admin_accounts, max_guests):
self.max_host_accounts = max_host_accounts
self.max_admin_accounts = max_admin_accounts
self.max_guests = max_guests
def save(self, *args, **kwargs):
if getattr(self, "plan_changed", ""): #you need to set this attribute whenever updating a plan. like model_obj.plan_changed = True
#otherwise you need to check db whether plan is changed or not.
self.set_plan(*self.PRICING_CHOICES[self.pricing_plan][1])
super(Organisation, self).save(*args, **kwargs)