How to mimic the url aliasing functionality of mod_rewrite with Pyramid (Python Framework)?

StackOverflow https://stackoverflow.com/questions/23314745

  •  10-07-2023
  •  | 
  •  

I'm working on converting an existing Drupal site to Pyramid. The Drupal site has urls that are SEO friendly example: "testsite.com/this-is-a-page-about-programming". In Drupal they have a system which maps that alias to a path like "testsite.com/node/33" without redirecting the user to that path. So the user sees "testsite.com/this-is-a-page-about-programming" but Drupal loads node/33 internally. Also if the user lands on "testsite.com/node/33" they would be redirected to "testsite.com/this-is-a-page-about-programming".

How can this be achieved in Pyramid without a major performance hit?

有帮助吗?

解决方案 2

You don't really need all this stuff with Pyramid - it can handle nice urls natively.

Basically, your "page" model would have a slug field which would store the SEO-friendly URL fragment:

class Page(Base):
    id = sa.Column(sa.Integer, primary_key=True)
    slug = sa.Column(sa.String, index=True, unique=True)
    title = sa.Column(sa.String)
    body = sa.Column(sa.String)

Then you would have a route which directly maps /:slug url's to a view which would find a page by its slug and render it.

For backward compatibility purposes you may also have a view mapped to /node/:id, which would simply redirect to the /:slug view, but that's only needed if you want to preserve the old redirects.

Here's another variation of your Page model:

class Page(Base):
    slug = sa.Column(sa.String, primary_key=True)
    title = sa.Column(sa.String)
    body = sa.Column(sa.String)
    historical_node_id = sa.Column(sa.Integer, index=True, unique=True)

UPDATE: Regarding "Is there something like a server level redirect for wsgi servers that could be coded into a file rather than having to make a database query and then redirecting?" - this is the very definition of premature optimization :)

The cost of a browser making a request, receiving a redirect and making another request is often in the order of hundreds of milliseconds, especially if the server is on another continent - purely because of speed of light. Full page loading usually in the order of seconds. The cost of fetching a single row from a database running on the same machine is usually less than a millisecond - hundreds of times faster than the redirect itself.

But, if you insist, there definitely are ways to do that:

  1. Hard-code the values in some dict:

    HISTORICAL_URLS_MAPPING = {
        '33': '/this-is-a-page-about-programming',
        '34': '/this-is-a-page-about-premature-optimization'
    }
    
    def historical_node_id_view(node_id):
        return HTTPFound(HISTORICAL_URLS_MAPPING[node_id])
    
  2. Normally a Pyramid app is served behind an "industrial" web server, such as Nginx or Apache. You can drop a bunch of configuration lines into the webserver config.

其他提示

In Pyramid, one way to achieve what you want is to use URL dispatch.

Suggest trying out the Quick Tutorial to get an idea of what Pyramid actually does.

mod_rewrite is a webserver module that is independent of the framework your application uses. If it is configured on the server, it should operate the same regardless of whether you are using Drupal or Pyramid. Since the module is the same for each framework, the overhead is precisely the same in both cases.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top