Django breadcrumb using generic tools - python

I would like to use Django build-in tools to print breadcrumb string in the html-template file, for example like this:
domain_name/accounts/14
Where each part between / will lead to its corresponding page. Is it achievable using {{ request.path }} and https://docs.djangoproject.com/en/1.9/ref/templates/builtins/ ?
The tasks I see:
Remove first slash '/' from the `{{ request.path }}'
Break {{ request.path}} value into pieces (divided by '/')
Apply link to each piece

I don't think the string manipulation you want to do is possible from the template side. I think a possible way is using a custom template filter that receives request.path and returns a list of tuples (link, text) and then iterate over that list on the template side and create the breadcrumbs.
https://docs.djangoproject.com/en/1.9/howto/custom-template-tags/#writing-custom-template-filters

Related

Sending and rendering HTML syntax via jinja variable

I need some complicated operations to render some dynamic trees in my front-end. But as I can't find any way to run recursion in my jinja or front-end, I take an approach to make a string in my views.py along with HTML syntax and render them in the front-end to get the desired output something like this (As an example, here I skip the original complicated string because there is no need for it):
in views.py:
test = "<h2>Hi This is from django</h2><ol><li>abc</li><li>mno</li><li>xyz</li></ol>"
mydict={
'test' : test,
}
return render(request, 'app\index.html', mydict)
In index.html:
<div class="container-fluid">
{{ test }}
</div>
My desired output with this code is:
Hi This is from
djangoabcmnoxyz
But the obtain output is:
<h2>Hi This is from django</h2><ol><li>abc</li><li>mno</li><li>xyz</li></ol>
Please suggest to me, is there any way to render the jinja string variable along with the effect of HTML in my front-end? If not then how can I take an approach to render any tree dynamically in my front-end where the level, leaf node, intermediate node, etc all info come from the database.
You can use the django-template-filter safe for this.
{{ test | safe }}

Search a value in HTML content with Django ORM that don't consider HTML tags

I have a field in database description that system will save HTML code in it.
and I have a search system that works with Q:
Post.objects.filter(Q(name__icontains=keyword) | Q(description__icontain=keyword))
It works fine but the problem refers to it when user searchs for example '<strong>' or 'strong' it will returns the rows that have '<strong>' word in them but it shouldn't consider the HTML tags.
So how to search a value in HTML content with Django ORM that don't consider HTML tags?
I'd probably add a second field called stripped_description and use django's striptags filter to strip out html tags, and have django search on that field. It should still find the row you need to recall the actual description field containing the HTML code, should you need to display that as a result, but that's the only means I've used to "ignore" html tags.
You can or probably should look into a proper search function using haystack, my favorite search engine to use with it is whoosh (pip install whoosh) if you are not doing hardcore search functions. You can define your content to be indexed like this:
{{ object.title }}
{{ object.description|strip_tags }}
It's fairly easy to setup, and once you have done it, setting up for the next project would be in minutes.
I think it's a good action:
from django.utils.html import strip_tags
rows = Post.objects.filter(Q(name__icontains=keyword) | Q(description__icontain=keyword))
if rows:
for j,i in enumerate(rows):
if keyword not in strip_tags(i.name) and keyword not in strip_tags(i.description):
del rows[j]
return render(request,'posts.html',{'rows':rows})
Fetching data from db with filter.
Strip tags the results and then filtering them again.

Django Templates - Iterate over range

Intention
In my Django template, I create a link for each letter in the alphabet and each digit 1-9 to link to an index page.
In Python code, this is what it would look like:
for ch in map(chr, range(97, 123)) + range(1,10):
print '{0}'.format(ch)
But I want to do this in a Django template, so I can't use the map/range functions directly.
Failed Attempts
At first, I thought about creating a template tag that returns the alphanumeric character list, and then looping over it in the template, but this does not work, as it's a tag and not a context variable.
Templatetag:
#register.simple_tag
def alnumrange():
return map(chr, range(97, 123)) + range(1,10)
Template:
{% for ch in alnumrange %}
{{ch}}
{% endfor %}
I thought it might work when using the with tag, but it didn't either.
Further thoughts
I can't set the context in a view as this is a base template which I extend.
I don't want to add a context processor, as I use this range only in a single template.
Is there a way to turn the template tag output into a context variable over which I can iterate? Or is there another way I should solve this?
Check out this template tag: Template range tag. You should be able to extend it to handle characters as well.
You need inclusion tag here. Just pass your range in context and render it as you like. It gives you flexible and modular structure.

Using python string formatting in a django template

Is there an easy way to use python string formatting from within a django template? That is, I'd like to be able to do something like this in a template
{{ variable|%.3f }}
I know in this case, one can just use
{{ variable|floatformat:3 }}
But I'd really like to be able to generically use any python string format on a django variable. In my system it's inconvenient to have to deal with two different ways to format output (python vs django), so I'd like to standardize. I could write a custom template tag like
{% pyformat variable format="%.3f" %}
or maybe a custom template filter like
{{ variable|pyformat:"%.3f" }}
Do either of these already exist? Will the customer filter work with a string passed in like that?
{{ variable|stringformat:".3f" }}
Source: http://docs.djangoproject.com/en/dev/ref/templates/builtins/#stringformat
stringformat
I had omit the "%":
{{ variable|stringformat:".3f" }}

Google appengine string replacement in template file

I'm using google appengine (python, of course :) ) and I'd like to do a string.replace on a string from the template file.
{% for item in items %}
<p>{{ item.code.replace( '_', ' ' ) }}</p>
{% endfor %}
But that isn't working. So we cannot execute anything other than basic checks in the app engine templates. Is that Correct ?
Another related problem is I'm trying to shorten a string and make it available to the template.
Each furniture object has a name and a longer description field. In this view I'm rendering, I want only the first 50 characters of the description field.
So I tried something like
items = db.GqlQuery( 'select * from furniture' )
# edit: if you change the above line to
# items = db.GqlQuery( 'select * from furniture' ).fetch( 1000 )
# the .fetch() command makes the addition of dynamic properties work!
for item in items :
item.shortdescr = item.description[ 0:50 ]
# pass data off to template for rendering
self.response.out.write(
template.render( 'furnitureAll.html', { 'items' : items } )
)
Template goes
{% for item in items %}
<p>{{ item.name }}</p>
<p>{{ item.shortdescr }}</p>
<!-- items.shortdescr does not exist here,
probably because I did not .put() it previously. -->
{% endfor %}
Since that didn't work, I tried changing the Gql Query to shorten the string instead. But I'm quickly realizing Gql isn't like SQL. I'm trying to write queries like
select name,LEFT( description, 50 ) from furniture
With little success
I have little experience with Google AppEngine, but my understanding is that it is very closely related to Django. Your templates do not actually contain Python code, even if some of the structures you use in them look like it.
Both of your questions should be solved using template filters. If it was Django, I would use something like this for your second question:
{{ item.description|truncatewords:10 }}
For your first question (string replace), there may be no built-in filter you can use for that. You will need to write your own. Something like this;
from google.appengine.ext.webapp.template import create_template_register
register = create_template_register()
#register.filter
def replace_underscores(strng):
return strng.replace('_', ' ')
Then, in your template, you can do this:
{{ item.code|replace_underscores }}
Apart from the argument-less .fetch() call in your code, which I believe can't possibly work (you ALWAYS have to pass fetch an argument -- the max number of entities you're willing to fetch!), I can't reproduce your problem -- assigning a new attribute (including one obtained by processing existing ones) to each item just works fine in my tests.
Can you please reproduce your observed problem in as tiny as compass as possible and edit your question to include all relevant files pls? Seems to be the only way we could help you with your weird observed bug!
BTW, select name,LEFT( description, 50 ) or whatever OF COURSE won't work in GQL -- GQL, very very explicitly, ONLY supports select * to get whole entities, or select __key__ to get just the entities' keys -- that's all; NO selectivity of columns in the select, much less any OPERATIONS on them!-)

Categories