32

I have an entry in my urls.py that acts as a catch-all which loads a simple view if it finds an appropriate page in the database. The problem with this approach is that the URL solver will then never fail, meaning that the APPEND_SLASH functionality won't kick in - which I need.

I'd rather not have to resort to adding a prefix to the static page URLs to stop it being a catch-all. I do know about flatpages, which uses a 404 hook rather than an entry in urls.py, and I had kinda hoped to avoid having to use it, but I guess this problem might be exactly the kind of reason why one would use it.

Any way round this problem or should I just give in and use flatpages?

nedned
  • 3,552
  • 8
  • 38
  • 41

2 Answers2

80

Make sure that your catch-all URL pattern has a slash at the end, and that the pattern is the last in your URLconf. If the catch-all pattern doesn't end with a slash, then it will match stray URLs before the middleware tries appending a slash.

For example, use r'^.*/$' instead of r'^.*' as your last pattern.

To do the same, but pass the url to the view as a named argument, use r'^(?P<url>.*)/$'.

Arthur Hebert-Ryan
  • 1,802
  • 18
  • 24
  • I would have accepted your answer. I'm dealing with this same question, but I can't ask it again, and all I can give is an upvote. Brilliant. – B Robster Aug 22 '12 at 22:54
  • I've finished up with this project so I can't test this out. But it makes sense and Ben's feedback is encouraging, so I'll just accept it. – nedned Nov 16 '12 at 06:34
  • 2
    The only shortcoming is that your catch all will no longer be there for URLs without a trailing slash – Jad S Sep 08 '16 at 21:30
  • 4
    It does catch URLs without a trailing slash, @JadS, because the middleware will append one to any URL that doesn't have one, _before_ it is compared against the the pattern. If you have APPEND_SLASH=False in your settings, then you're right that this solution won't catch those. The OP was specific about this setting, though. – Arthur Hebert-Ryan Sep 12 '16 at 18:15
  • When using the flatpages app, `r'^(?P.*)/$'` results in a duplicate trailing slash being added. Omitting the slish from the regex (to leave `r'^(?P.*)$'`) fixes this. – Micah Walter Apr 04 '18 at 16:52
  • Django warns about $ saying it should be removed – Vaibhav Vishal Oct 19 '18 at 09:51
0

The statement if it finds an appropriate static page in the database seems like your static pages are not quite static so, you either pass your links through urls.py (just like you do now), or you extract those pages from the DB, put them in a directory and configure that directory as one for serving static files

Tudor Constantin
  • 26,330
  • 7
  • 49
  • 72
  • Well, ok not strictly static. In fact they actually get parsed as markdown in a very simple template so they can't be served up as html files. So yeah 'static' is misleading... ok well just wrong. I've edited the question to remove that description. And the reason I don't just manually add an entry for each one is that I want it to function like a CMS, where users can create pages without having to touch the source files. – nedned Jul 01 '11 at 09:42