How to unittest valid img src links in a template response - python

I have a view that renders a template with an image:
<html>
...
<img src="/static/img/mypic.jpg" />
...
</html>
I want to write a unit test that asserts this img src is valid and does not return a 404 broken link.
def test_myimage(self):
response = self.client.get('/static/img/mypic.jpg')
However, although I know this link is in fact valid, the test returns 404.
Why does this occur and how can I test valid img src links?

The easiest way is to use Django's built-in static file tools documentation here. Then you can use something like <img src="{% static 'mypic.jpg' %}" /> and Django will take care of making sure the file exists. If you use this, then you don't need to write unit tests for static files at all.

Related

Image is not shown in django template,

I have a django template where i send an image actually its for an email.It only works when i keep the whole url like abc.com/images/a.png .
i have sent he image like this:
{
'picture':picture.url
}
This is the code for template that i am using for email template:
<img src="{{picture}}" alt="image" width="200" height="200" >
Am i missing something? as it only works when i keep the whole url?
To build an absolute URL you can use request.build_absolute_uri(picture.url) in your view.

Is there any way to implement list of different links in Flask application?

I am trying to create a blog page where my requirement is to list a group od links in a html page.
app.py:
#app.route("/blog")
def blog():
return render_template('blog.html')
blog.html:
{% extends "index.html" %}
{% block content %}
<ul>
<li>
Chapter 1
</li>
<li>
Chapter 2
</li>
<ul>
{% endblock content %}
Stored all my html pages in templates directory.
I am able to open the localhost:8000/blog where I can view all the Chapter1, chapter2 links, but when I click on the link I get error:
http://localhost:5000/templates/chapter%201.html
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
I am sure that this will not work as it is pointing to different URL, can some one guide how do I implement the list of Chapter in Flask app?
If you had the static html files already, you should serve it as static file as mentioned in document here. Then, put urls for these files in your main page:
url_for('static', filename='chapter1.html')
The templates directory is not linked to a URL, the files in that directory are not 'published'. You shouldn't put files there you intent to serve without processing (executing the templates).
With the default configuration only files in the static directory are accessible via the /static/ URL path prefix, see the Static Files section of the Flask Quickstart.
The intent for the templates directory is for the files to be loadable as Jinja2 templates using the render_template() function, where you use that function in endpoint functions you registered with Flask for specific URLs.
You may want to try out the Flask tutorial first, it covers both templates and static files in more detail.
For a blog site, the normal pattern would be for you to store the blog post data in a database or text files in some way Python can easily load, then use a single template to render the contents. You'd register a URL with a pattern, which would call a function that can load any blog page data, then use the blog page template to render the output:
#app.route('/blog/<page_name>')
def blog_page(page_name):
page_data = load_blog_page(page_name)
if not page_data: # no page? Produce a not found error.
abort(404)
return render_template('blog_page.html', **page_data)
The above function will be called when a browser visits URLs that start with /blog/, and is called with the next part as the page_name variable; e.g. /blog/chapter-1 would result in page_name being set to 'chapter-1'. Note that URLs can't have spaces in them (spaces would have to be encoded to %20 for the URL to still be a URL).
The function then loads the page data (with a load_log_page() function you'd have to write yourself), then provided page_data is not empty or None or some other false-y value indicating that the page doesn't actually exist, uses the render_template() function to produce HTML output. render_template() will use the file templates/blog_page.html as the template file here, and page_data is assumed to be a dictionary whose key-value pairs make the variables the template can use.

Extending a base tpl file and editing the body of it in bottle

I am familiar with flask, and trying hands on bottle module. I wanted to have a single base.tpl file which can have an editable body and the other tpl files could extend this base file and edit in its body to change the content. Like in flask, using jinja, we could use {% block bodyContent %}{% endblock %} and insert the html body content later when needed. How can we achieve the same with bottle module?
Bottle comes with jinja2 support, out of the box. Here's a toy example, just to illustrate. Note that you may prefer to use Bottle's jinja2_view rather than return a template directly.
from bottle import jinja2_template
app = Bottle()
home_template = '''
{{greeting}} - Thanks for stopping by.
'''
app.route('/')
def home():
return jinja2_template(home_template, greeting='Hello!')
You can find examples of more advanced usage here.
Actually bottle comes with this solution built into it's own template engine.
https://bottlepy.org/docs/dev/stpl.html#template-functions
include(sub_template, **variables)
Render a sub-template with the specified variables and insert the resulting text into the current template. The function returns a dictionary containing the local variables passed to or defined within the sub-template:
% include('header.tpl', title='Page Title')
Page Content
% include('footer.tpl')
rebase(name, **variables)
Mark the current template to be later included into a different template. After the current template is rendered, its resulting text is stored in a variable named base and passed to the base-template, which is then rendered. This can be used to wrap a template with surrounding text, or simulate the inheritance feature found in other template engines:
% rebase('base.tpl', title='Page Title')
<p>Page Content ...</p>
This can be combined with the following base.tpl:
<html>
<head>
<title>{{title or 'No title'}}</title>
</head>
<body>
{{!base}}
</body>
</html>

Frozen flask creates the files but gets the links wrong

Using frozen flask to make my website static, I have the following problem.
While all of my pages are being built (file//c:/correctpath/build/2014/page-title/index.html) the links to the pages are file:///c:/2014/page-title/.
Is there something I have missed?
EDIT:
In my template I have something like
{% for page in pages %}
{{ page.title }}
{% endfor %}
where .url() is a method on the page object:
return url_for('article', name=self.name, **kwargs)
url_for produces absolute paths (e. g. /2014/page-title) - when you open up your files in the browser it follows the rules regarding relative URL resolution and strips the extra file contents. If you just want to view your files as they will be seen on the server, Flask-Frozen has a run method that will let you preview your site after generating it.
Alternately, you can set FREEZER_RELATIVE_URLS to True to have Flask-Frozen generate links with index.html in them explicitly.
Rather than setting FREEZER_RELATIVE_URLS = True, with resulting URLs ending on index.html, you can also set FREEZER_BASE_URL to <http://your.website/subdir>.

How to parse Django templates for template tags

Situation
I'm writing a checker program that checks Django templates. For example I want to check if all Django templates that use url template tag, use it with quotes on first parameter so that it is Django 1.5 compatible. Also I want to check that they have included {% load url from future %} in their templates.
For example if my program parses the following Django template, I want it to raise an exception.
{% extends 'base.html' %}
<td>
<a href="{% url first second %}">
</a>
</td>
But this template should get parsed without exception.
{% extends 'base.html' %}
{% load url from future %}
<td>
<a href="{% url 'first' second %}">
</a>
</td>
I'm not limited to this simple example. I have other parsings to do. For example I want to check how many load template tags are present in the template.
Question
How can I elegantly solve this parsing problem?
I don't want to use regular expressions.
I this Django it self has some utilities in this regard. I think using them is a good idea, but I don't know how.
I want to run the program separately from Django. So I don't want Django to run the program itself (with render_to_response). (This is important)
Code
Please show me some code that can solve the example I mentioned. I want to detect whether {% load url from future %} is in the code. Also I want to check every url template tag and check if the first argument is quoted.
Bonus:
I want to be able to see the rendered HTML that Django generates from this template, and do my HTML parsing on it. (for example with PyQuery)
You say...
I want to check if all Django templates that use url
template tag, use it with quotes on first parameter so that it is
Django 1.5 compatible.
...and...
I don't want to use regular expressions.
...because...
the result of that might become a huge spaghetti code
...but, frankly, writing a parser from scratch is likely to be even messier than using a regular expression. I don't see what's so messy about a regex as simple as something like...
"{% *url +[^']"
...and I doubt there's a non-regex-based solution that's as terse as that.
With regards to...
Also I want to check that they have included
{% load url from future %} in their templates.
If your intention is to ensure Django 1.5 compatibility, this is pointless. According to the Django 1.5 release notes, the new-style url tag syntax is enabled by default, so the line {% load url from future %} won't have any effect.
And in versions prior to 1.5, it's much simpler just to put...
import django.template
django.template.add_to_builtins('django.templatetags.future')
...at the bottom of your settings.py and be done with it. :-)
You can also use the compile_string method.
>>> from django.template.base import *
>>> settings.configure()
>>> compile_string("<a href='ab'></a>{% cycle 'row1' 'row2' as rowcolors %}", None)
>>> [<Text Node: '<a href='ab'></a>'>, <django.template.defaulttags.CycleNode object at 0x10511b210>]
The compile string method is utilized by the Template class and is the method used to produce the node list.
Tested in Django 1.8 Alpha.
https://github.com/django/django/blob/1f8bb95cc2286a882e0f7a4692f77b285d811d11/django/template/base.py
Next code still uses django, but it can check if syntax is correct:
>>> from django.template import Template
>>> from django.template.defaulttags import URLNode
>>> t = Template("{% load url from future %}\n{% url projects_list company.slug %}")
>>> for node in t.nodelist:
... if isinstance(node, URLNode):
... for arg in node.args: print(arg)
...
company.slug
>>> t2 = Template('{% load url from future %}\n{% url "projects_list" company.slug }')
>>> for node in t2.nodelist:
... print(node)
...
<django.template.defaulttags.LoadNode object at 0x32145d0>
<Text Node: '
{% url "projects_list" c'>
>>>
As you see last node is not URLNode

Categories