Django模型中的外键数组

5 投票
2 回答
10836 浏览
提问于 2025-04-18 14:57

我不太确定这个标题是否合适,但我在简单表达这个问题时遇到了困难。基本上,我正在创建一个模型,用来表示一个商家。这包括地址、营业时间等等。而营业时间正是让我感到困惑的地方。我已经有了地址。

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

所以每个商家都有一个或多个地址。我想在营业时间上也做类似的事情。

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

我想要确保每个商家必须有一个包含7个“每天营业时间”的数组——每个数组项对应一周中的一天。我似乎找不到一个明显又优雅的方法来实现这一点。在django中有没有好的方法来建模这个?

2 个回答

0

我遇到过类似的问题(需要为一天的每个小时设置很多字段),得出了以下结论:

在Django中,最简单的方法就是不要想太复杂。如果你需要七次相同的一堆字段,那就直接复制粘贴这些字段,并给它们加上不同的后缀或前缀。例如:

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()中通过遍历工作日来做一些智能的操作。

4

使用 ManyToManyField:

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天,可以查看 限制创建模型实例的数量

撰写回答