先看代码:
class ItemBase(models.Model):
owner = models.ForeignKey(User, related_name='%(class)s_related', on_delete=models.CASCADE)
title = models.CharField(max_length=250)
created = models.DateField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
def __str__(self):
return self.title
def render(self):
return render_to_string('courses/content/{}.html'.format(self._meta.model_name), {'item': self})
class Text(ItemBase):
content = models.TextField()
class File(ItemBase):
file = models.FileField(upload_to='files')
class Image(ItemBase):
file = models.FileField(upload_to='images')
class Video(ItemBase):
url = models.URLField()
在上述代码中,我们定义了一个ItemBase的抽象类,因此在其Meta类中设置了abstruct=True。由于字段owner定义与一个抽象类中,因而需要针对每个字模型使用不同的related_name。对于related_name属性中的model类名,Django可将占位符指定为%(class)s。据此,每个子模型的related_name将自动生成。由于我们将%(class)s_related用作related_name,因而子模型的逆向关系分别表示为text_related,file_related, image_related, video_related。
注:获取模型类名: obj._meta.model_name。(其中obj为模型对象,通过_meta属性可访问Meta类的属性)