In Pyramid, how do I return raw HTML from a view?

2019-02-26 20:16发布

问题:

I'm really new to Pyramid (and pretty new to web frameworks in general).

I'm trying to get to the stage where I can return raw HTML from a view, so that I can markup data returned from my mongoDB store.

My __init__.py in my pyramid project is standard:

def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
config = Configurator(root_factory = Root, settings = settings)
config.add_view('hermesweb.views.my_view',
                context = 'hermesweb:resources.Root',
                renderer = 'hermesweb:templates/mytemplate.pt')
config.add_static_view('static', 'hermesweb:static', cache_max_age = 3600)
views.myDB = connect() # connect to my mongoDB

My templates/mytemplate.pt looks like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal">
<head><title>My test title. . . </title></head>
<body>
    <div>
        <h2>Perform a search</h2>
        <form method="GET" action="">
            <div>
                <input type="text" name="id"/>
            </div>
            <input type="submit" value="Submit"/>
        </form>
        <h2>Results</h2>
        ${results}
    </div>
</body
<html>

Finally, my views.py looks like this:

myDB = "" # ref to the database is assigned on startup.
def my_view(request):
    key = request.GET.get('id', None)
    results = ""
    if key:
        db_res = myDB.call_some_find_function(key)
        for data in db_res:
            results = "%s <li> %s </li>" % (results, data)
        results = "<ul> %s </ul>" % results

    return {'results': results}

When I insert a term into the form and the my_view function gets called the database is queried and the correct results get pulled out, however, rather than the string being returned turning into html in the webpage, it is printed as a string in the web-page instead.

I suspect this is something to do with the content type? But I don't really understand Pyramid well enough yet. Can someone explain how to get this to return html that is interpreted by the browser as html, rather than just a string?

Extra question - should I be even using the views.py for this type of database call? I'm still confused where the whole Root object comes into it. I'm using MongoDB as the database backend. . .

回答1:

To prevent Chameleon from escaping the ${result} variable, you need to use ${structure: result}, as per the documentation: http://chameleon.readthedocs.org/en/latest/reference.html#structure



回答2:

The string is being escaped, which is the default for strings inserted into templates to prevent naughty code being injected into your site. To mark the string as safe, you'll want to mark it as a literal so it's not escaped. I believe that pyramid (like pylons) ships with the webhelpers module, so you can import the literal function:

from webhelpers.html import literal

then replace your final results assignment with:

results = literal("<ul> %s </ul>" %results)

If literal doesn't ship with pyramid as I suspect, see this post: Python Pyramid & Chameleon templating language escapes html

edit: note that you should probably be escaping your data from your db before you input it into the html for safety's sake. You can use cgi.escape for this.