我有一个RoutingUrl模型,它描述了我的网站上使用的所有网址以及视图(View模型的外键),它必须管理网址和其他一些路由信息。网址的大小不断增加,也应该支持重定向。模型或多或少如下:
class RoutingUrl(models.Model):
url = models.CharField(unique=True, verbose_name='routing url')
crc_checksum = models.IntegerField(editable=False)
redirect_to = models.ForeignKey('RoutingUrl', related_name='redirect_from', blank=True, null=True)
view = models.ForeignKey(View, related_name='routing_urls')
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
class View(models.Model):
name = models.CharField()
RoutingUrl还有一个通用外键,模型包含有关要呈现的页面的信息(必须支持不同的模型,这就是通用外键的原因)。
现在的问题是:如何实现这样的动态路由到django?我的感觉是我有两种选择:
你能否告诉我两种选择中哪一种最适合实施这样的路由?当然,如果有第三个更好的选择,请不要犹豫向我推荐。
答案 0 :(得分:1)
调查django中间件钩子,很明显process_request不是实现路由功能的最佳候选者。的确,从文档中可以看出:
它应该返回None或HttpResponse对象。如果它返回 没有,Django将继续处理此请求,执行任何请求 其他process_request()中间件,然后是process_view()中间件, 最后,适当的观点。 如果它返回HttpResponse 对象,Django不会打扰任何其他请求,视图或 异常中间件或适当的视图;它会应用响应 中间件到那个HttpResponse,并返回结果。
因此,HttpResponse将破坏中间件堆栈功能。 process_view或多或少相同,这将避免异常中间件的调用。在这一点上,采用第二种选择似乎更聪明......
django-cms插件证实了这种直觉,正如您从urlpatterns定义的source code中看到的那样:
from django.conf import settings
from django.conf.urls import url
from cms.apphook_pool import apphook_pool
from cms.appresolver import get_app_patterns
from cms.views import details
# This is a constant, really, but must live here due to import order
SLUG_REGEXP = '[0-9A-Za-z-_.//]+'
if settings.APPEND_SLASH:
regexp = r'^(?P<slug>%s)/$' % SLUG_REGEXP
else:
regexp = r'^(?P<slug>%s)$' % SLUG_REGEXP
if apphook_pool.get_apphooks():
# If there are some application urls, use special resolver,
# so we will have standard reverse support.
urlpatterns = get_app_patterns()
else:
urlpatterns = []
urlpatterns.extend([
url(regexp, details, name='pages-details-by-slug'),
url(r'^$', details, {'slug': ''}, name='pages-root'),
])