首页 > 解决方案 > Django:在设计模型之间的关系时需要帮助

问题描述

我有一个应用程序,它允许将多个板子关联到每个客户,板子我可以上传与客户相关的文件,以决定相关网站页面的外观。

所以我需要建模的关系是:

  1. 一个客户,多个板子;
  2. 一个董事会,一个客户;
  3. 一板多档;

让我们专注于前两个

模型.py

class Board(models.Model):
    title               = models.CharField(max_length=120, verbose_name="Titolo")
    description         = models.TextField()
    files               = models.FileField( null=True, blank=True, upload_to = 'clients_download_area',  verbose_name = 'Client Reserved File')
    date                = models.DateTimeField(auto_now_add=True, verbose_name = 'Data di pubblicazione')

    def __str__(self):
        return str(self.title)

class Client(models.Model):
    name    = models.CharField(max_length=30)
    address     = models.CharField(max_length=120)
    boards  = models.ManyToManyField(Board, blank=True)

    def __str__(self):
        return str(self.name)

好的,关系#1 完成。但是,如果我需要知道哪个客户与董事会相关联(关系#2)怎么办?

如果我将新字段设置为 Board Class

class Board(models.Model):
   [...]
   client               = models.ForeignKey(Client, blank = True)

当然,当我makemigrationsDjango 抱怨时,因为它不知道Client是什么,因为我在下一个模型中定义了它。

我该如何设计这个数据库?

提前感谢您提供的任何帮助

标签: djangodjango-models

解决方案


这里的问题是你在构造之前引用了一个标识符(这里Client)(因为在类之前Board定义)。Client

Django 对此有一些支持:您可以传递包含模型名称的字符串。在同一个应用程序中,您可以使用ClassName,对于另一个应用程序,您可以使用other_app.ClassName,如文档所述:

如果需要在尚未定义的模型上创建关系,可以使用模型的名称,而不是模型对象本身:

from django.db import models

class Car(models.Model):
    manufacturer = models.ForeignKey(
        'Manufacturer',
        on_delete=models.CASCADE,
    )
    # ...

class Manufacturer(models.Model):
    # ...
    pass

所以在这里你可以这样写:

class Board(models.Model):
    title = models.CharField(max_length=120, verbose_name="Titolo")
    description = models.TextField()
    files = models.FileField( null=True, blank=True, upload_to = 'clients_download_area',  verbose_name = 'Client Reserved File')
    date = models.DateTimeField(auto_now_add=True, verbose_name = 'Data di pubblicazione')
    client = models.ForeignKey(
        'Client',
        related_name='my_boards'
        on_delete=models.CASCADE
    )

    def __str__(self):
        return str(self.title)

class Client(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=120)
    boards = models.ManyToManyField(Board, blank=True)

    def __str__(self):
        return str(self.name)

但是请注意,您已经定义了ManyToManyFieldClient到的关系Board。尽管有可能同时存在两个这样的关系并不常见。

如果你定义了ForeignKeyBoardto的关系Client,那么 Django 会自动创建一个反向关系(与related_name),这样some_client.my_boards,就是所有相关Boards 的管理者。


推荐阅读