这可能很长,但在我的制作中使用它之前我真的需要你的帮助.我有一个类Asset,它是其他类的基类(如Photo,Question,Video等).基本上它是一个多表继承.我需要这个来获取模板中用户的所有帖子或所有对象.它做我想要的.但我注意到,许多人反对多表继承,并且有些人不鼓励使用多表继承.所以,我真的需要你使用多表继承的一般意见.而且,我还有其他选择吗?或者有没有其他方法来获得用户的所有对象(资产)?请帮我决定做什么.我正在使用
django和postresql.如果我不清楚,请问我.如果有人能指导我完成这件事,我将非常感激和感激.
谢谢.
这是我的模特:
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)
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 Album(Asset):
title = models.CharField(max_length=200)
description = models.TextField()
def __unicode__(self):
return self.__class__.__name__
class Picture(Asset):
description = models.TextField()
image = models.ImageField(upload_to=get_upload_file_name)
album = models.ForeignKey(Album, null=True, blank=True, default = None)
def __unicode__(self):
return self.__class__.__name__
class BackgroundImage(Picture):
pass
class ProfilePicture(Picture):
pass
class Tag(models.Model):
title = models.CharField(max_length=40)
description = models.TextField()
def __unicode__(self):
return self.title
class Question(Asset):
title = models.CharField(max_length=200)
description = models.TextField()
tags = models.ManyToManyField(Tag)
def __unicode__(self):
return self.title
class Answer(Asset):
description = models.TextField()
question = models.ForeignKey(Question)
def __unicode__(self):
return self.description
最佳答案 现在我已经考虑了一些,我想建议使用Django
contenttypes framework进行通用关系的另一种解决方案.之前我没有注意到你有2级继承(即Asset-> Picture-> BackgroundImage).我之前的回答仍然有效,但您必须添加子模型的显式链接.这将允许您干净地拥有所有资产类型的资产链接,反之亦然.
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
注意Asset中的content_object字段.我还建议你为图片PictureAssetBase制作一个ABC(注意抽象=真如docs here中的解释)并且有PictureAsset,BackgroundImageAsset& ProfilePictureAsset继承自那.
所有资产类型模型都与Asset via GenericRelation呈反向关系.这样,您可以自由添加新资产类型,而对其他模型的影响最小.在您的视图等中,您显然需要为每种类型提供特殊处理,但您可以通过Asset中的content_type字段确定链接的资产类型,或者添加显式类型字段并自行处理.