【问题标题】:Array of foreign keys in Django ModelDjango模型中的外键数组
【发布时间】:2014-07-27 16:48:41
【问题描述】:

我不确定这是不是最好的标题,但我很难用简单的措辞来表达。基本上,我正在创建一个代表企业的模型。这包括地址,营业时间等。这是让我绊倒的营业时间。我有我的地址

class Address(models.Model):
    --snip--
   Business = models.ForeignKey(BusinessInfo)

因此,每个企业都有一个或多个位置地址。我希望在 Hours 上做类似的事情

class HoursOnDay(models.Model):
    open = isOpen = models.BooleanField()
    open = models.TimeField(null=True)
    closed = models.TimeField(null=True)

我要强制执行的是,每个企业都必须有一组 7 HoursOnDay - 一个用于一周中的每一天。我似乎无法偶然发现这样做的明显,优雅的方式。有没有什么好的方法可以在 django 中进行建模?

【问题讨论】:

    标签: python django


    【解决方案1】:

    使用多对多字段:

    class HoursOnDay(models.Model):
        is_open = models.BooleanField()
        open = models.TimeField(null=True)
        closed = models.TimeField(null=True)
    
    class Day(models.Model):
        hours = models.ManyToManyField(HoursOnDay)
    
    class Business(models.Model):
        days = models.ManyToManyField(Day)
    

    如果您想有 7 小时和 7 天的限制,您可以查看 Limit number of model instances to be created

    【讨论】:

    • 那一天是哪一天? (只是指出您需要比此处显示的更多样板才能完成这项工作)。
    • 这只是示例,您可以添加所需的属性
    • 这看起来很完美。如果我这样做,是否有意义(并且是 djano 方式!)到某个地方,也许在 init 中用一周中的 7 天填充业务模型中的天数字段?基本上,如果企业主通过管理员创建新位置并鼓励他们添加所有 7 天,那就太好了。
    • Business.__init__() 启动 7 天还为时过早(尚未存储模型的外键,效果不佳)。在已保存业务模型的post_create 信号处理程序中执行此操作。在这样的设置中更新营业时间也需要在更新视图定义中产生相当大的开销。我们是否还考虑了访问这些简单属性所需的数据库命中数,您需要应用一些prefect_related 来解决这种建模问题吗?但继续做你自己的经历:)
    • 我的建议(是的,我做了另一个答案)是最简单也是迄今为止最有效的方法。这是所有其他建议都应与之进行比较的基准。
    【解决方案2】:

    我遇到了类似的问题(一天中的每个小时都需要一堆字段)并得出以下结论:

    做到这一点最djangoish的方法是不要尝试做任何聪明的事情。如果您需要七次一堆字段,只需复制粘贴字段并给它们不同的后缀或前缀。例如:

    class Business(models.Model):
        --snip--
        monday_is_open = models.BooleanField()
        monday_opens_at = models.TimeField(null=True)
        monday_closes_at = models.TimeField(null=True)
    
        tuesday_is_open = models.BooleanField()
        tuesday_opens_at = models.TimeField(null=True)
        tuesday_closes_at = models.TimeField(null=True)
    
        wednesday_is_open = models.BooleanField()
        wednesday_opens_at = models.TimeField(null=True)
        wednesday_closes_at = models.TimeField(null=True)
    
        ...
    
        sunday_is_open = models.BooleanField()
        sunday_opens_at = models.TimeField(null=True)
        sunday_closes_at = models.TimeField(null=True)
    

    当然美国人(和其他人?)会从星期天开始,但你明白了。

    采用这种方法可以大大简化更新营业时间的过程。这种方法(以及您要求的方法)无法模拟每周更改营业时间,但这可能也不是您的需要。

    另外,如果您关心模式规范化,请去掉 is_open,而只需使用 xxx_opens_at__isnull=True, xxx_closes_at__isnull=True 即可,而您会使用 xxx_is_open=True

    您仍然可以在 Business.clean() 的工作日内通过迭代做一些聪明的事情。

    【讨论】:

      猜你喜欢
      • 2015-03-07
      • 2019-02-06
      • 1970-01-01
      • 2016-01-05
      • 2013-01-17
      • 1970-01-01
      • 2019-07-17
      • 2019-07-19
      • 2015-01-29
      相关资源
      最近更新 更多