这可能很长,但在我的制作中使用它之前我真的需要你的帮助。我有class Asset
,这是其他base class
的{{1}}等。)基本上是classes (like Photo, Question, Video
。我需要这个来获取模板中的所有帖子或用户的所有对象。它做我想要的。但是我注意到,很多人反对Multiple Table Inheritance
,有些人气馁Multiple Table Inheritance
。所以,我真的需要你使用Multiple Table Inheritance
的一般意见。而且,我还有其他选择吗?或者是否有任何其他方法可以获得Multiple Table Inheritance
的所有对象(assets
)?请帮我决定做什么。我正在使用django和postresql。如果我不清楚,请问我。如果有人能指导我完成这件事,我将非常感激和欣赏。
谢谢。
这是我的模特:
User
答案 0 :(得分:1)
所以我认为你正在做某种时间线应用。我的建议是让您的Asset
模型与您的不同资产类型建立OneToOneField
关系。所以你的Asset
模型看起来像是:
class Asset(models.Model):
user = models.ForeignKey(User, related_name = "user_objects")
likes = models.ManyToManyField(User, through="Like", related_name="Liked_user")
comments = models.ManyToManyField(User, through="Comment", related_name="Commented_user")
timestamp = models.DateTimeField(auto_now = True, auto_now_add= False)
updated = models.DateTimeField(auto_now = False, auto_now_add = True)
album = models.OneToOneField(Album, null=True, blank=True)
picture = models.OneToOneField(Picture, null=True, blank=True)
question = models.OneToOneField(Question, null=True, blank=True)
answer = models.OneToOneField(Answer, null=True, blank=True)
# etc...
class Meta:
ordering = ['-timestamp']
def __unicode__(self):
return self.__class__.__name__
Album
,Picture
,Question
& Answer
将不再继承Asset
,但会成为标准模型。
通过这种方式,您可以在公共集合中拥有资源,并根据需要对它们进行排序/显示。然后,根据哪个字段不为空,这将是单个资产的“类型”。需要进行一些手动检查以确定类型并确保资产不是空的,但它们不同,以至于它们无论如何都需要自定义处理。我以前曾多次做过这种事情,但它对我的用例来说很好。
答案 1 :(得分:1)
现在我已经考虑过这个了,我想建议另一个使用Django contenttypes framework解决通用关系的解决方案。之前我没有注意到你有2级继承(即Asset-> Picture-> BackgroundImage)。我之前的回答仍然可行,但您必须添加到子模型的显式链接。这样您就可以干净地Asset
链接到您的所有资产类型,反之亦然。
class Asset(models.Model):
user = models.ForeignKey(User, related_name = "user_objects")
likes = models.ManyToManyField(User, through="Like", related_name="Liked_user")
comments = models.ManyToManyField(User, through="Comment", related_name="Commented_user")
timestamp = models.DateTimeField(auto_now = True, auto_now_add= False)
updated = models.DateTimeField(auto_now = False, auto_now_add = True)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
class Meta:
ordering = ['-timestamp']
def __unicode__(self):
return self.__class__.__name__
class Like(models.Model):
asset = models.ForeignKey(Asset)
liked_by = models.ForeignKey(User)
liked_time = models.DateTimeField(auto_now = True, auto_now_add = False)
def __unicode__(self):
return "%s likes %s" % (self.liked_by, self.asset)
class Comment(models.Model):
asset = models.ForeignKey(Asset)
comment_by = models.ForeignKey(User)
liked_time = models.DateTimeField(auto_now = True, auto_now_add = False)
def __unicode__(self):
return "%s likes %s" % (self.comment_by, self.asset)
def get_upload_file_name(instance, filename):
return "uploaded_files/%s_%s" %(str(time()).replace('.','_'), filename)
class AlbumAsset(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
asset = generic.GenericRelation(Asset)
def __unicode__(self):
return self.__class__.__name__
class PictureAssetBase(models.Model):
description = models.TextField()
image = models.ImageField(upload_to=get_upload_file_name)
album = models.ForeignKey(Album, null=True, blank=True, default = None)
asset = generic.GenericRelation(Asset)
def __unicode__(self):
return self.__class__.__name__
class Meta:
abstract = True
class PictureAsset(PictureAssetBase):
pass
class BackgroundImageAsset(PictureAssetBase):
pass
class ProfilePictureAsset(PictureAssetBase):
pass
class Tag(models.Model):
title = models.CharField(max_length=40)
description = models.TextField()
def __unicode__(self):
return self.title
class QuestionAsset(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
tags = models.ManyToManyField(Tag)
asset = generic.GenericRelation(Asset)
def __unicode__(self):
return self.title
class AnswerAsset(models.Model):
description = models.TextField()
question = models.ForeignKey(Question)
asset = generic.GenericRelation(Asset)
def __unicode__(self):
return self.description
请注意content_object
中的Asset
字段。我还建议您为照片制作ABC PictureAssetBase
(注意abstract=True
作为docs here中的说明)并PictureAsset
,BackgroundImageAsset
& ProfilePictureAsset
继承了这一点。
所有资产类型模型都通过Asset
与GenericRelation
具有反向关系。通过这种方式,您可以自由添加新资产类型,而对其他模型的影响最小。在您的视图等中,您显然需要为每种类型提供特殊处理,但您可以通过Asset
中的content_type字段确定链接的资产类型,或者添加显式类型字段并自行处理。