django – 需要帮助 – 模型设计

这可能很长,但在我的制作中使用它之前我真的需要你的帮助.我有一个类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字段确定链接的资产类型,或者添加显式类型字段并自行处理.

点赞