python Django - DRF多对多和外键

o8x7eapl  于 2023-01-08  发布在  Python
关注(0)|答案(1)|浏览(147)

我正在为娱乐管理构建一个API。
用户可以创建空项目或项目与表演,旅游和节日。用户也可以创建表演和指定项目的ID。
项目可以包含:
1.显示0到 *

  1. 0至 * 之旅
    1.节日0至 *
    浏览可以包含:
    1.显示0到1
    节日可以包含:
    1.显示0到 *
    演出、巡回演出和节庆活动必须是项目的一部分。
    以下是我的模型:
class Project(models.Model):
    """Models for Projects"""
    name = models.CharField(max_length=255, unique=True)
    shows = models.ManyToManyField('Show', blank=True)
    festivals = models.ManyToManyField('Festival', blank=True)
    tours = models.ManyToManyField('Tour', blank=True)
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    date_created = models.DateTimeField(auto_now_add=True)
    last_update = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

class Show(models.Model):
    """Models for Shows"""
    name = models.CharField(max_length=255, unique=True)
    start_date = models.DateTimeField(default=timezone.now, blank=True)
    end_date = models.DateTimeField(default=timezone.now, blank=True)
    tours = models.ManyToManyField('Tour', blank=True)
    festivals = models.ManyToManyField('Festival', blank=True)
    projects = models.ForeignKey(Project, on_delete=models.CASCADE, default=None)
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    date_created = models.DateTimeField(auto_now_add=True)
    last_update = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

class Tour(models.Model):
    """Models for Tour."""
    name = models.CharField(max_length=255, unique=True)
    start_date = models.DateTimeField(default=timezone.now, blank=True)
    end_date = models.DateTimeField(default=timezone.now, blank=True)
    production = models.CharField(max_length=255, blank=True)
    shows = models.ForeignKey(Show, on_delete=models.CASCADE, blank=True, null=True)
    projects = models.ForeignKey(Project, on_delete=models.CASCADE, default=None)
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    date_created = models.DateTimeField(auto_now_add=True)
    last_update = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

class Festival(models.Model):
    """Models for Festival."""
    name = models.CharField(max_length=255, unique=True)
    start_date = models.DateTimeField(default=timezone.now, blank=True)
    end_date = models.DateTimeField(default=timezone.now, blank=True)
    address_1 = models.CharField(max_length=128, blank=True)
    address_2 = models.CharField(max_length=128, blank=True)
    city = models.CharField(max_length=64, default="Paris")
    state = models.CharField(max_length=25, default='France')
    zip_code = models.CharField(max_length=8, default="92000")
    gps = models.CharField(max_length=255, blank=True)
    technical_rider = models.FileField(null=True, upload_to=riders_file_path)
    shows = models.ForeignKey(Show, on_delete=models.CASCADE, blank=True, null=True)
    projects = models.ForeignKey(Project, on_delete=models.CASCADE, default=None)
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    date_created = models.DateTimeField(auto_now_add=True)
    last_update = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

一切正常,但我对m2m / foreignkey之间的双重关系有疑问:

class Project(models.Model):
    """Models for Projects"""
    shows = models.ManyToManyField('Show', blank=True)

AND

class Show(models.Model):
    """Models for Shows"""
    projects = models.ForeignKey(Project, on_delete=models.CASCADE, default=None)
y1aodyip

y1aodyip1#

你的实现是不正确的。在Django中,当你指定关系时,你只做了其中的一面。你似乎对这些模型应该有什么类型的关系感到困惑。
一个项目可以有多个节目吗?看起来可以。一个节目可以是多个项目的一部分吗?
如果第二个问题的答案是肯定的,那么您应该使用多对多关系。如果答案不是肯定的,那么这应该是一对多关系。

**M2M示例:**从功能上来说,你把ManyToManyField放在哪里并不重要。它创建了一个对称关系。但是你应该把它放在模型中最有意义的地方。这是你可以从Django管理员那里访问和更新关系信息的模型

# m2m example 
class Project(models.Model):
    shows = models.ManyToManyField(Show, related_name="projects")

class Show(models.Model):
    ...

1到M示例:

# one-to-many example
class Project(models.Model):
    ...

class Show(models.Model):
    ...
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="shows")

这两个实现不能(绝对不应该)混淆,因为它们定义了不同类型的关系。如果你很难理解它们之间的区别,我建议你 checkout this video(显然不是全部)。一旦你确定了你需要哪种类型的关系,实现你的Django模型并理解你可以用它们做什么就像儿戏一样。

相关问题