Django:在设计模型之间的关系时需要帮助

时间:2018-09-24 15:50:53

标签: django django-models

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

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

  1. 一个客户,多个董事会;
  2. 一个董事会,一个客户;
  3. 一个板,多个文件;

让我们专注于前两个

models.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)

当然,当我makemigrations抱怨时,Django因为不知道客户端是什么,因为我在下一个模型中对其进行了定义。

如何设计该数据库?

在此先感谢您提供的帮助

2 个答案:

答案 0 :(得分:3)

这里的问题是,在构造标识符之前,您要引用(在Client之前)(因为在{em>之前定义了BoardClient类)。

Django为此提供了一些支持:您可以传递包含模型名称的 strings 。在同一个应用程序中,您只能使用ClassName,对于另一个应用程序,您可以使用other_app.ClassName,就像documentation所说的那样:

  

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

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的{​​{1}}关系。尽管有可能同时存在两个这样的关系不是很普遍。

如果您定义了从BoardForeignKey的{​​{1}}关系,那么Django会自动创建一个 reverse 关系(使用Board),这样Client是所有相关related_name的经理。

答案 1 :(得分:2)

我认为您可以传递模型类名而不是类本身:

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