Reputation: 95
I have a RoutingUrl model which describes all the urls used on my site with the view (foreign key to the View model) that has to manage the url and some other routing information. The urls are continuously growing in size, and should also support the redirect. The models are more or less the following:
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()
The RoutingUrl has also a generic foreign key with the model containing information about the page to be rendered (different models has to be supported, this is the reason for the generic foreign key).
Now the question is: how to implement such a dynamic routing into django ? My feeling is that I have two options:
Could you suggest me which of the two options is the best to implement such a routing ? Of course if there is a third, better option, don't hesitate to suggest it to me.
Upvotes: 2
Views: 3447
Reputation: 95
Investigating a bit into the django middleware hooks, it become evident that the process_request is not the best candidate for implementing the routing functionality. Indeed, from the documentation:
It should return either None or an HttpResponse object. If it returns None, Django will continue processing this request, executing any other process_request() middleware, then, process_view() middleware, and finally, the appropriate view. If it returns an HttpResponse object, Django won’t bother calling any other request, view or exception middleware, or the appropriate view; it’ll apply response middleware to that HttpResponse, and return the result.
So an HttpResponse will break the middleware stack functionalities. It's more or less the same for the process_view, which will avoid the calls of the exception middlewares. At this point it seems more smart to adopt the second option...
The django-cms plugin confirm this intuition, as you could see from the source code of the urlpatterns definition:
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'),
])
Upvotes: 1