Django Error TemplateSyntaxError only occuring in production - python

So I've got either a doozy of an issue, or I'm over looking the obvious.
I am getting a TemplateSyntaxError and it's only occurring in production. I temporary turned on DEBUG and it provided zero useful information. I have an index.html page, that loads my tags, it then calls the inclusion tag.
My setup is Django 1.6.5 and using the default Mezzanine setup. (Fabric, Nginx, Gunicorn). Development environment is OpenSuse 12.2 and the deployment environment is some version of Ubuntu (hosted on AWS EC2).
This issue only occurs on the production side and NOT in the development environment. Originally I made the tag a regular tag, and it wasn't even being called at all. The server would silently fail, and act as though it had never attempted to call the tag. (I used logging to prove that it never went into the tag). Now that it is an inclusion_tag (which is what it should be), I get this exception.
Here is the file system paths where the relevant pieces are.
project
bactt_core
templates
base.html
index.html
blog
includes
blog_post_list_include.html
templatetags
__init__.py
bactt_blog_tags.py
The error exactly is
TemplateSyntaxError at /
Invalid block tag: 'get_blogs_by_category', expected 'endblock'
Here is the portion of my index.html template where I am making the call to the inclusion tag. It is dying on the get_blogs_by_category, which is an inclusion_tag. Inside bactt_blog_tags.
<div id="news" class="row">
<div class="panel">
<div class="panel-body">
<h2>News</h2>
{% load bactt_blog_tags %}
{% get_blogs_by_category "News" %}
</div>
</div>
</div>
Here is bactt_blog_tags
from django import template
from django.core.exceptions import ObjectDoesNotExist
#from mezzanine import template
from mezzanine.blog.models import BlogPost, BlogCategory
register = template.Library()
MAX_BLOG_POSTS_TO_RETURN = 5
#register.inclusion_tag('blog/includes/blog_post_list_include.html')
def get_blogs_by_category(categoryTitle):
category = None
postList = []
try:
category = BlogCategory.objects.get(title__exact=categoryTitle)
except ObjectDoesNotExist:
return {'blog_posts':[]}
if category:
for post in BlogPost.objects.all():
categories = post.categories.all()
if category in post.categories.all():
postList.append(post)
if len(postList) > MAX_BLOG_POSTS_TO_RETURN:
postList = postList[0:MAX_BLOG_POSTS_TO_RETURN]
return {'blog_posts': postList}
Thanks for any help you can provide I've already spun my wheels for a least a few hours now.
Edit:
So I renamed the file bactt_blog_tags.py to bb_tags.py and everything now works. I have no idea what the reason for this naming issue is but if somebody could explain that, I would definitely call this answered. Why whatever pathing occurs in development vs. production is also odd.

What ended up being the fix was changing the name of the template tag filename.
It seems that for some reason using bactt_blog_tags.py created some sort of issue, or possible collisions, that were only happening in production.
What is odd to me is that I didn't have any applications called bactt_blog that might have conflicted. The application directory was bactt_core.
I changed the name to bbtags.py and everything worked.

Your TemplateTags directory should be called templatetags.
Django is case-sensitive here because it's a Python module name (hence the __init__.py in the template tag dir).
You also have an uppercase letter in your Templates dir, but that doesn't matter as it's evaluated as part of a filesystem path, not as a Python import.

Related

Flask app rendering some variable urls from HTML docs in folder but not others HTML docs in the same folder

My Flask app renders all templates in the template folder, including all blog posts in a blog folder within the templates folder. However, I have the exact structure for my app's glossary as I have for the blog - a folder called 'glossary' within the templates folder. But, it's quirky. It renders some html documents but not others from that same folder. It renders 0-day.html every time I click a link with that dynamic url or directly type in /0-day; but not act.html using /act. I have 180 html files in the glossary folder and about half render and the rest return a 404.
I've been researching this for a month now, and today I switched the glossary structure by creating a blueprint instead. I used this tutorial: https://www.youtube.com/watch?v=WteIH6J9v64. I got everything running as normal, except the same issue with the glossary persists with the blueprint setup as well.
Assuming everything else works, and it does:
Glossary Term:
#glossary.route("<termname>", methods=["POST","GET"])
def term(termname='story'):
try:
visits(termname)
return render_template(f"{termname}.html", glossary=True, termname=termname)
except Exception as e:
return page_not_found(e)
As you can see below, I have my blog setup the same way:
Blog Posts
#app.route("/blog/<postname>", methods=["POST","GET"])
def post(postname='distant-idealism-introduction'):
try:
visits(postname)
return render_template(f"/blog/{postname}.html", blog=True, postname=postname)
except Exception as e:
return page_not_found(e)
The only difference is that the blog is routed from the routes.py now and the glossary terms from the glossary.py blueprint. However, when there was no blueprint I was rendering everything from the routes.py file, so the blueprint setup is not the cause.
I apologize, but because this problem is so confusing, I don't know what else to add. It's even difficult to research because I always get results like the YouTube video above - either about blueprints, building routes, or something Flask in general. I never get any search result even close to my issue. If more info is required just let me know, please.
Thank you in advance.
Some problems I found:
The URL rule is missing a start slash:
#glossary.route("/<termname>", methods=["POST","GET"])
Since your templates about glossaries were put in a glossary folder, your template path should be /glossary/act.html:
return render_template(f"/glossary/{termname}.html", glossary=True, termname=termname)

trouble querying an SQL database held on a Flask app - returning "None" in Flask when it returns data when I interact with the database

I'm working in a Flask app, and I'm trying to set it up to create dynamic webpages based on the data in the SQL database. For example, if we scrape data about a certain criminal, I want Flask to route my requests such that I can type:
myflaskapp.com/criminal/[criminal's name]/
and be taken to a page specifically for that criminal. This is the relevant portion of the views.py that I've already written:
#app.route('/criminal/<first_name>')
def criminal(first_name):
criminal = Individual_Criminal.query.filter_by(first_name=first_name).first()
return render_template('user.html',
criminal=criminal)
Now, when I call the Individual_Criminal.query.filter_by(first_name=first_name).first() in a Python shell, it returns as expected:
However, when I set up my Flask server, and do (what I believe to be) the exact same command query, it just gives me a blank page (with my navbar and stuff extended from the base html.)
The HTML for the page I'm trying to call is simple:
<!-- extend base layout -->
{% extends "base.html" %}
{% block content %}
<h1>{{ criminal.full_name }}</h1>
<hr>
{% endblock %}
As you can see, it should be returning the particular criminal's full name (in this case, Bryan Sanford). Instead, it returns this:
Instead of the requested criminal's full name, the way that the HTML specifies.
Where am I going wrong here? My thinking is that if I can do that exact query that's in my views.py file and have it return the correct value, it should work the same in my Flask app. However, clearly there are some wires crossed somewhere. Can any of you wonderful people help me untangle this?
edit: as discussed in one of the answers comments, when I change views.py to include print(criminal.first_name), it fails, throwing AttributeError: 'NoneType' object has no attribute 'first_name'. Even though the exact same line works exactly as expected in the actual database!
Your routing seems to be wrong?
This is not the same
myflaskapp.com/[criminal's name]/
as
#app.route('/criminal/<first_name>')
Try
myflaskapp.com/criminal/[criminal's name]/

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>.

Caught NoReverseMatch while rendering, but have matching URL name

As the title implies I've got the NoReverseMatch error, but my url.py has the corresponding named url. I feel pretty confident I've missed something simple, but being new I can't seem to find my own problem.
ERROR: (Generated in the below employee_edit.html file)
Caught NoReverseMatch while rendering: Reverse for ''employee_new''
with arguments '()' and keyword arguments '{}' not found.
\home\username\mysite\myapp\views.py:
class v_EmployeeCreate(CreateView):
model = Employee
template_name = 'employee/employee_edit.html'
def get_success_url(self):
return reverse('employee_list')
\home\username\mysite\url.py:
from myapp.views import v_EmployeeCreate, v_EmployeeList
urlpatterns = patterns('',
< ... snip ...>
url(r'^newEmployee$', v_EmployeeCreate.as_view(), name="employee_new"),
)
\home\username\mysite\myapp\templates\employee\employee_edit.html (line 7):
<form action="{% url 'employee_new' %}" method="POST">
I feel like there is a file path issue, but I'm not sure how I would resolve that. The named URL works to get me to the template, but then the template itself fails to generate a url.
For the sake of documentation so far I have:
reloaded django
checked spelling
confirmed non-template functionality (Same setup without the template tags is fine. page loads)
Working from tutorial: http://effectivedjango.com/tutorial/views.html#creating-contacts
I think you are using an old version of Django - before 1.5 (current is 1.6). The clue is that your error message has two single-quotes around the view name: in those older versions, you shouldn't put quotes around the name in the url tag.
You should (preferably) upgrade Django, or (if you really can't do that) use {% url employee_new %}

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