【问题标题】:Is it possible to add a datetime column to a manytomany field?是否可以将日期时间列添加到多对多字段?
【发布时间】:2013-07-21 18:30:33
【问题描述】:

我想知道是否有一种方法可以将 datetime auto_now_add=True 列添加到 manytomany 字段。 我有以下型号。

class Photographer(models.Model):
     user = models.OneToOneField(User, primary_key=True)
     bio = models.CharField(max_length=140, blank=True)
     favorites = models.ManyToManyField('Photo', through='Favorites', related_name = 'photographer_favs')
     likes = models.ManyToManyField('Photo', related_name='likedby', blank=True)

在我的 postgresql 数据库中,我有一个名为“djangoapp_photographer_likes”的单独表。

在这张表中,我有三列:

id                 photographer_id        photo_id
[PK] serial        integer                integer
    1                  3                    6
    2                  3                    7
    3                  3                    8

在投入制作几个月后,我意识到我需要知道我们喜欢这些照片的日期时间。因此,我将有四列而不是三列:

    id             photographer_id        photo_id      liked
[PK] serial        integer                integer       timestamp with time zone
    1                  3                    6           2013-07-10 23:30:19.559463+00
    2                  3                    7           2013-07-11 17:00:53.39614+00
    3                  3                    8           2013-07-11 17:25:28.4953+00

即使模型中没有这个额外的列,是否可以添加它?我想要它,以便每次喜欢一张图片时,都会记录它被点赞的时间。如果这不可能,我应该考虑哪些其他解决方法?

编辑

这是我的照片模型:

class Photo(models.Model):
     title = models.CharField(max_length=40, blank=True)
     photographer = models.ForeignKey(Photographer, related_name = 'shot_owner')
     postTime = models.DateTimeField(auto_now_add=True)
     description = models.CharField(max_length=255, blank=True)
     url = models.CharField(max_length=128)

【问题讨论】:

  • 关系表(解决两个实体表之间的多对多关系)具有属性是很常见的。我们只想确保属性是关系的属性,而不是实体之一,或者本身不是实体。

标签: python django postgresql datetime django-models


【解决方案1】:

是的,这很正常。您将为 Likes 关系声明一个显式模型并在其上添加 datetime 字段。查看many-to-many field docs 以获取完整的详细信息和一些示例 - 组成员身份示例包括一个“加入日期”字段,该字段与您喜欢的时间戳相同。在字段定义中使用auto_now_add=True 应该会自动记录时间戳。

class Photographer(models.Model):
    # as above, but:
    likes = models.ManyToManyField('Photo', through='PhotoLikes', related_name='likedby', blank=True)

class PhotoLikes(models.Model):
    class Meta:
        db_table = 'djangoapp_photographer_likes'
        # or whatever your table is called
    photo = models.ForeignKey(Photo)
    photographer = models.ForeignKey(Photographer)
    liked = models.DateTimeField(null=True, blank=True, auto_now_add=True)

正如文档所述,创建喜欢的方法在此设置中受到更多限制:

与普通的多对多字段不同,您不能使用添加、创建或赋值(即 beatles.members = [...])来创建关系

为什么?您不能只在 Person 和 Group 之间创建关系 - 您需要指定 Membership 模型所需的关系的所有细节。简单的 add、create 和 assignment 调用不提供指定这些额外细节的方法。因此,对于使用中间模型的多对多关系,它们被禁用。创建这种类型关系的唯一方法是创建中间模型的实例。

在这种情况下,理论上可以确定额外的细节,因为它是一个自动时间戳,但 Django 并不能完全检测到。

【讨论】:

  • 感谢您的快速回复,即使 likes 已经是 Photo 的 ManyToMany 外键,我会遇到问题吗?
  • 还有!我相信它是 auto_now_add :)
  • 您需要确保模型使用您现有的表,可能通过重命名现有表或为中间模型使用Meta 类上的db_table 设置。或者通过适当地选择中间模型的名称。当然,您必须自己添加数据库列 - syncdb 不会这样做,因为它位于现有表上。
  • 谢谢。我有 Django South,它将处理列添加。我已经编辑了我的问题并在其中添加了我的照片模型以进行澄清。如果可以,您能否给我一个更明确的答案,以便我接受并投票赞成您的答案?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-09
  • 1970-01-01
  • 1970-01-01
  • 2018-04-24
相关资源
最近更新 更多