Django遗传和永久性

2024-09-30 10:34:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我在django中创建了一个简单的CMS,有多个“模块”(每个模块都是django应用程序)。我设置了以下模型:

class FooObject(models.Model):
    id = models.SlugField(primary_key=True)
    name = models.CharField(max_length=255)
    creator = models.ForeignKey(auth.models.User, editable=False, related_name="createdby")

class FooPage(FooObject):
    content = models.TextField(blank=True, null=True)

    @models.permalink
    def get_absolute_url(self):
        return ('page', (), {'page_id':self.id}

class FooSubitem(FooObject):
    parent = models.ForeignKey(FooPage, related_name='subitems')

在每个模块中,我创建了FooPage的一个子类,以及FooSubitem的至少一个子类,例如

^{pr2}$

以及

# in FooGallery.models
class FooGallery(FooPage):
    location = models.CharField(max_length=255)

    @models.permalink
    def get_absolute_url(self):
        return ('gallery', (), {'gallery_id':self.id})

class FooImage(FooSubitem):
    image_file = models.ImageField(upload_to='foogallery')

这些都是简单化了,但应该能让你对我要做的事情有一个很好的了解。在FooPost和FooImage的admins中,我将父选择列表限制为它们对应的父页面。在

当我试图在模板中使用这些时,我的问题就出现了。在每个视图中,我都有以下内容:

page_list = FooPage.objects.all()

它返回所有FooPages的列表,包括FooBlog和FooGallery类型。但是,当我遍历这个列表时:

{% for page in page_list %}{{ page.get_absolute_url }}{% endfor %}

它返回“page”url模式,而不是“blog”或“gallery”url模式。在

当我以后想添加一个FooCalendar模块时,如何在不重写代码的情况下实现这一点?我想确保这能和任何可能的模块一起工作。在

谢谢

  • 雷克索

Tags: 模块nameselfidtrueurlgetmodels
3条回答

使用django-model-utils中的InheritanceManager可以避免添加内容类型字段。在

然后,如果在查询集上调用.select_subclasses,它将向下转换所有对象,例如:

FooPage.objects.select_subclasses().all()

这个问题的经典解决方案往往是adding a ContentType to the superclass which stores the type of subclass for that instance。这样,您就可以依赖于一个一致的API,该API返回相应类型的相关子类对象。在

FooPage.objects.all()返回FooPage类型的所有对象,这些对象将是FooPage、FooBlog、FooGallery的底层db表行的混合。要获得正确的URL,您应该获取FooBlog或FooGallery对象,例如

page.fooblog.get_absolute_url()

如果页面只是一个页面对象,即通过FooPage创建的,那么它可能会抛出FooBlog.DoesNotExist错误,所以为了获得正确的url,您可以做如下操作

^{pr2}$

或者,如果不希望FooPage成为真正的表,可以尝试将FooPage设置为抽象类。在

相关问题 更多 >

    热门问题