首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多个django模型值取决于选择字段值

多个django模型值取决于选择字段值
EN

Stack Overflow用户
提问于 2017-11-08 12:00:19
回答 2查看 1.5K关注 0票数 1

我的Django模型有一个pricing_plan选项字段。有12个字段的值依赖于pricing_plan值。

代码语言:javascript
复制
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,这些字段都会得到特定的值。在可以描述如下的代码中:

代码语言:javascript
复制
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类?
  • 使用组织作为父类,并创建以下子类:

代码语言:javascript
复制
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)
  • 还要别的吗?
EN

回答 2

Stack Overflow用户

发布于 2017-11-08 12:17:41

我会这样做(我使用django-选项包进行伪Enum仿真):

代码语言:javascript
复制
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)
票数 0
EN

Stack Overflow用户

发布于 2017-11-08 13:00:07

我想

代码语言:javascript
复制
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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47179188

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档