📅  最后修改于: 2023-12-03 15:00:26.602000             🧑  作者: Mango
在Django中,我们可以使用ForeignKey
或ManyToManyField
来建立模型之间的关系。这些字段使用related_name
参数指定反向关系的名称。反向关系指的是反过来查找其他模型中与它相关的模型对象。
例如,如果我们有两个模型Book
和Author
,并且我们想要在Author
模型中查找与该作者相关的所有图书,则可以这样编写Book
模型:
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
在这里,我们使用related_name='books'
指定了反向关系的名称。现在,我们可以通过以下方式获得该作者的所有图书:
author = Author.objects.get(pk=1)
books = author.books.all()
抽象类是一种不能直接实例化的类,而是用来作为其他类的基类或模板的类。在Django中,我们可以使用抽象类来避免重复编写相似的代码。抽象类可以定义字段、方法和其它属性,而子类可以继承这些属性,从而避免了重复定义。
例如,我们可能有多个模型都需要一个日期字段和一个描述字段。我们可以用抽象类来定义这些字段,然后继承这个类。这样,我们就不必在每个模型中都定义这些字段。
以下是一个示例:
class TimeStampedModel(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Person(TimeStampedModel):
name = models.CharField(max_length=200)
class Book(TimeStampedModel):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
在这里,我们定义了一个抽象类TimeStampedModel
,其中包含created
和updated
两个字段。我们将abstract=True
添加到抽象类的Meta
选项中,以表明它是一个抽象类,不能直接实例化。
我们可以在Person
和Book
模型中继承TimeStampedModel
类,从而避免了重复编写日期字段。例如,在Person
模型中使用继承:
class Person(TimeStampedModel):
name = models.CharField(max_length=200)
当我们使用抽象类时,Related_name可能会有所不同。回到我们之前的示例,如果我们希望访问与TimeStampedModel
关联的所有模型,则可以将related_name
指定为%(class)s_related
,其中%(class)s
将被实际模型的名称所替换。
以下是代码示例:
class TimeStampedModel(models.Model):
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
ordering = ['-created']
class Person(TimeStampedModel):
name = models.CharField(max_length=200)
class Book(TimeStampedModel):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
class Magazine(TimeStampedModel):
name = models.CharField(max_length=200)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, related_name='%(class)s_related')
在这里,我们添加了一个新的模型Magazine
,它与TimeStampedModel
关联,并且related_name
设置为%(class)s_related
。因此,我们可以通过以下方式获得与TimeStampedModel
关联的所有模型:
publisher = Publisher.objects.get(pk=1)
magazines = publisher.magazine_related.all()
books = publisher.book_related.all()
people = publisher.person_related.all()
Related_name和抽象类是Django中非常有用的概念。Related_name允许我们方便地反向访问与模型相关的对象,而抽象类则可以帮助我们避免重复编写代码。它们的结合使用可以使我们的代码更加简洁和易于理解。