How to insert the content of text file in django template? - python

Django 1.7. I need to insert the content of text file from the model in django template. It's important that it must be a file not a text field of the model.
Is there a way to do it?
Here is my model:
class Model1(models.Model):
file1 = FilerFileField(null=True, blank=True)
file2 = FilerFileField(null=True, blank=True)
I tried {% include %} tag and it doesn't work.

{% include %} is for including templates (which will be searched in settings.TEMPLATE_DIRS) so no surprise it doesn't work.
Mainly, you'll have to read the files from Python code and pass it to the template's context. Three possible solutions here:
1/ add a method to your model to get your FilerFileField's content
2/ write a custom template filter (or tag) that takes the FilerFileField and returns the file's content
3/ read the FilerFileField's contents in the view and add them to the context

Tag include is not about inserting something from model into your template. Is about inserting content of specified template. You need to write custom template filter which will read your file content and return it into template:
from django import template
register = template.Library()
#register.filter
def print_file_content(f):
try:
return f.read()
except IOError:
return ''
And use it into template like:
<div>{{ object.file1|print_file_content }}</div>
Or you can pass it through template context. Then just read file content into your view and add this content to your template context dictionary.

Related

How to use Django session variable in models.py

I wanna use the Django session variable on models.py file. How can I do it?
I want to get the user's Pincode/zip and have to run a query using that.
pin_code = #wanna get from session
price = ProductPrice.objects.get(product=self.pk, pincode=pin_code)
I need to get Pincode from the session.
In your model method you don't have access to the request so you do not have access to the session. One way that you could call the method with the session is to add a template tag that passes the value from the session to your method
#register.simple_tag(takes_context=True)
def price(context, product):
return product.get_price(pin_code=context.request.session.get('pin_code'))
In your template you would use the following, if the above code was added to a file with the path app_name/templatetags/product_tags.py
{% load product_tags %}
{% price item %}
Docs on where to put custom template tags

Replace some text to bold in django template

I have a variable
text = "replace some word"
in a view. I want to replace 'some' to bold. Like this:
"replace **some** word"
How to handle that variable in django template?
Obviously, the ** do not make a bold string in a template and you will have a much harder time trying to replace these markers with appropriate opening and closing tags in the template, e.g via a custom filter. However, you can make it bold in the view by applying the necessary HTML there and marking it safe:
# views.py
from django.utils.safestring import mark_safe
# in your view
# ...
text = "replace some word"
# add the appropriate html tags
text = text.replace('some', '<strong>some</strong>')
# now you have to mark it as safe so the tags will be rendered as tags
text = mark_safe(text)
# ...
return render(reqest, template, {.., 'text': text, ...})
Now you can just use it like a normal variable in the template via {{ text }}
You can create custom template tags to render these type of things. You have to write some extra lines of code. But once you do, it's reusable and less tedious to use replace function every time.
Create a custom tag/filter file called mytags.py, your app layout might look like this:
myapp/
__init__.py
models.py
templatetags/
__init__.py
mytags.py
views.py
Write in mytags.py:
from django import template
register = template.Library()
def bold(text):
return text.replace('**','<strong>',1).replace('**','</strong>',1)
register.filter('bold', bold)
In your template, first load the custom tag file:
{% load mytags %}
Apply this custom tag to the text:
{{ text|bold }}
For reference: https://docs.djangoproject.com/en/2.1/howto/custom-template-tags/

How to show images in Django Template with out static?

I have an API which gives me a list of movies, and there images are in HTTP links like:
https://d2gx0xinochgze.cloudfront.net/5/public/public/system/posters/12/thumb/Tevar-Movie-Opening-Day-Box-Office-Collection-Report-1140x752_1482917123.jpg
So in django we use static file {% static 'image.jpg' %} to display images in templates, But how to display api images links in template?
{% static 'image.jpg' %} doesn't magically make the image show up in the website, django renders the template with what its been given. Static means take a look at the statics folder, search for the given parameter as a file, and get the url for that given static asset.
In your particular case, you say you get the url of the images. You can easily add those urls to context, which is then gonna be a part of the rendering process.
For a function view it would roughly look like this.
def view(request, *a, **kw):
template = loader.get_template('my_template.html')
context = {'my_image': get_image_from_api()}
return HttpResponse(template.render(context, request))
For a class based view it would roughly look like this.
class MyView(TemplateView):
template_name = 'my_template.html'
def get_extra_context(self):
_super_context = super().get_extra_context()
context = {'my_image': get_image_from_api()}
return {**_super_context, **context}
For both of these views, which are roughly the same; you now can use {{my_image}} inside the template to refer to the url. Hope it helps!
Fetch the images via python in views per say. Pass them through your context when rendering the page. Use django's template tags to put the URLs within tags.

Render django application within TextField

I am creating an application to display articles. In my model, I have a TextField that will contain the content of the article.
Now I would like to be able to render another application within my article. Let say I have a poll application and I would like to display a poll in the middle of the article. How can I do that ?
I tried by putting a {% render_poll 42 %} within the post but, as expected, it just display that within the generated page.
Should I create some kind of tag (like let say [poll=42]) and parse it before displaying the rendered html page ? (I use the markdown library, maybe I could extend it.) How can I do that to stay in a nice "django friendly" way ? I want that, when in the admin panel, I can easily insert poll (or other apps) within an article.
You could compile the TextField string as a template. Ie.:
from django.db import models
from django.template import Template, Context
class YourModel(models.Model):
body = models.TextField()
def render_body(self, context=None):
template = Template(self.body)
context = context or {}
context['object'] = self
return template.render(Context(context))
Then in the actual template, you could use {{ your_model.render_body }} rather than {{ your_model.body }}.

render cms page within another page

Im trying to render a cms page, within another page using a custom cms plugin.
The this is my plugin class:
class PageInDiv(CMSPlugin):
page_div = models.ForeignKey(Page, verbose_name= "page")
def __unicode__(self):
return self.page_div.get_title()
as you can see all it does is link the plugin to a page then on my cms_plugins.py i have
class PageInDivPlugin(CMSPluginBase):
model = PageInDiv
name = _("Page in div")
render_template = "page.html"
admin_preview = False
def render(self, context, instance, placeholder):
temp = loader.get_template(instance.page_div.get_template())
html = temp.render(context)
context.update({
'html': html,
'title':instance.page_div.get_title(),
'placeholder':placeholder,
})
return context
as you can see i pass the html for the provided page to the plugin template, then the plugin template is rendered within the page thats hosting the plugin.
The problem i am having is that the placeholder content from the page thats selected via foreignkey is not being rendered ( displayed ).
So my question is, is there a way to render a pages placeholders programatically ?
Just for a moment ignoring the idea of creating a custom plugin in order to do what you describe (ie, render a page's placeholders programatically), the following might be a viable alternative, depending on what exactly you are trying to achieve...
You should be able, just in the template for your "outer" cms page (ie, the page within which you want to display the contents of another cms page), to get access to the current page like this:
{{ request.current_page }}
This is by virtue of the cms page middleware. So taking that a step further, you should be able to access the page's placeholders like this:
{% for placeholder in request.current_page.placeholders %}
{{ placeholder.render }}
{% endfor %}
That's one way you could go about rendering a page's placeholders "inside" another page.
I needed to render another page from within the template which could be accomplished with:
#register.simple_tag(takes_context=True)
def render_page(context, page, default="base.html"):
if not page:
return loader.get_template(default).render(context)
new_context = copy(context)
new_context['request'] = copy(context['request'])
new_context['request'].current_page = page
new_context['current_page'] = page
new_context['has_change_permissions'] = page.has_change_permission(context['request'])
new_context['has_view_permissions'] = page.has_view_permission(context['request'])
if not new_context['has_view_permissions']:
return loader.get_template(default).render(context)
return loader.get_template(page.get_template()).render(new_context)

Categories

Resources