我在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模块时,如何在不重写代码的情况下实现这一点?我想确保这能和任何可能的模块一起工作。在
谢谢
使用django-model-utils中的InheritanceManager可以避免添加内容类型字段。在
然后,如果在查询集上调用
.select_subclasses
,它将向下转换所有对象,例如:这个问题的经典解决方案往往是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对象,例如如果页面只是一个页面对象,即通过FooPage创建的,那么它可能会抛出
^{pr2}$FooBlog.DoesNotExist
错误,所以为了获得正确的url,您可以做如下操作或者,如果不希望FooPage成为真正的表,可以尝试将FooPage设置为抽象类。在
相关问题 更多 >
编程相关推荐