How to show images in Django Template with out static? - python

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.

Related

Include a simple function inside Django HTML template

I currently have a function called "copyright" (a dynamic copyright message) that I am trying to include into my base Django template, like below:
def copyright():
some code
some more code
print(finaloutput)
I have it sitting in my modules/utils.py which is in my assets directory which I have registered in my static directories.
I want to be able to call that function like {{ copyright }} straight in my top level base.html inside my main templates folder.
I have tried everything to ensure I am loading the staticfiles with no luck. Am I approaching this the wrong way?
Unfortunately almost everything you're doing here is wrong.
This has nothing to do with static files: as you said yourself, this is a dynamic function so isn't static by definition. Anyway, you can't put Python code in your assets directory. And finally, any function like this will always need to return the result, not print it.
What you need here is a template tag, which you put in your app's templatetags directory and register via the decorator:
#register.simple_tag
def copyright():
some code
some more code
return finaloutput
Then, load the tags in your template and call it as a tag, not a variable:
{% load utils %} # or whatever you called the file
...
{% copyright %}
See the template tags docs.
There are several ways to achieve your end goal, but nothing you are doing will get you there.
You can,
Use template tags.
Use context processors, in several different ways.
Use {{ view.function_name }} as-is in your templates if you are using class based generic views from Django.
Judging from how I think you have things set up, the fastest way could be to just pass in some context data in your views.
If you are using functional views, your code can look something like this:
def my_view(request):
def copyright():
return "copyright 2018"
return render('my_template.html', {'copyright': copyright})
If you are using class based generic views, you can simply modify your get_context_data.
class Home(TemplateView):
def get_context_data(self, *args, **kwargs):
ctx = super(TemplateView, self).get_context_data(self, *args, **kwargs)
ctx['copyright'] = self.copyright()
return ctx
def copyright(self):
return "copyright 2018"

Globally getting context in Wagtail site

I am working on a Wagtail project consisting of a few semi-static pages (homepage, about, etc.) and a blog. In the homepage, I wanted to list the latest blog entries, which I could do adding the following code to the HomePage model:
def blog_posts(self):
# Get list of live blog pages that are descendants of this page
posts = BlogPost.objects.live().order_by('-date_published')[:4]
return posts
def get_context(self, request):
context = super(HomePage, self).get_context(request)
context['posts'] = self.blog_posts()
return context
However, I would also like to add the last 3 entries in the footer, which is a common element of all the pages in the site. I'm not sure of what is the best way to do this — surely I could add similar code to all the models, but maybe there's a way to extend the Page class as a whole or somehow add "global" context? What is the best approach to do this?
This sounds like a good case for a custom template tag.
A good place for this would be in blog/templatetags/blog_tags.py:
import datetime
from django import template
from blog.models import BlogPost
register = template.Library()
#register.inclusion_tag('blog/includes/blog_posts.html', takes_context=True)
def latest_blog_posts(context):
""" Get list of live blog pages that are descendants of this page """
page = context['page']
posts = BlogPost.objects.descendant_of(page).live().public().order_by('-date_published')[:4]
return {'posts': posts}
You will need to add a partial template for this, at blog/templates/blog/includes/blog_posts.html. And then in each page template that must include this, include at the top:
{% load blog_tags %}
and in the desired location:
{% latest_blog_posts %}
I note that your code comment indicates you want descendants of the given page, but your code doesn't do that. I have included this in my example. Also, I have used an inclusion tag, so that you do not have to repeat the HTML for the blog listing on each page template that uses this custom template tag.

Changing css styles from view in Django

Sorry in advance if there is an obvious answer to this, I'm still learning the ropes with Django.
I'm creating a website which has 6 pre determined subjects (not stored in DB)
english, civics, literature, language, history, bible
each subject is going to be associated with a unique color.
I've got a template for a subject.html page and a view that loads from the url appname/subject/subjectname
what I need to do is apply particular css to style the page according to the subject accessed. for example if the user goes to appname/subject/english I want the page to be "themed" to english.
I hope I've made myself clear, also I would like to know if there is a way I can add actual css code to the stylesheet and not have to change attributes one by one from the back-end.
thanks very much!
In templates you can use conditionals for add css, like this:
<div class="{% if subject=='civics' %}civic-class{% endif %}"></div>
For this, subject value should come from view.
Now, for themed page, you could use the extends tag. Let's supose:
def your_view(request):
subject # Here you get the url subject, 'how' is up to you
if subject == 'english'
template_base = '/some/html/tenplate.html'
elif subject == 'civis':
template_base = '/some/other/template.html'
... # then you return 'template_base' variable to template
Then in template:
{% extends template_base %} # at the top
Hope this helps, is the same logic if you use Class-Based views.
Django's views are not responsible for the presentation, it's the template (and css etc of course)'s reponsability. Now assuming you have the same view serving different subjects, the view obviously need to know which is the current subject (I assume from a captured part of the url passed as argument to the view), so it can easily pass this information to the template, which in turn can use it to add a subject-specific class to the body tag. Then you only have to write your css accordingly.
As an example:
# urls.py
patterns = urlpatterns('',
#...
url(r'whatever/(P?<subject>[a-z-]+>)/$', 'myviews.index', ...),
)
# myviews.py
def index(request, subject):
# do whatever
context = {
# whatever else
'subject':subject
}
return render(request, "whatever/index.html", context)
# whatever/index.html
<html>
# headers etc
<body class="something {{ subject }} etc">
# whatever here
</body>
</html>
You can do this is many ways.
In general you need to return some variable from your view to the html and depending on this variable select a style sheet, if your variable name will match you style sheet's name you can do "{{variable}}.css", if not you can use JQuery.

Using variables in Django model content

i like to use the url template tag in my model's content.
example:
models content:
Car.description = 'this is a link to our main page: home'
in template.html:
<div>{{ Car.description }}</div>
result
<div>this is a link to our main page: home
is it possible, or do i have to write my own template tag?
thanks in advance
Roman
Assuming you have this:
car.description = 'this is a link to our main page: home'
You can do:
from django.template import Context, Template
from django.core.urlresolvers import reverse
class Car(models.Model):
def description_with_url(self):
return Template(self.description).render({'url': reverse('home')})
or use the same logic in custom template tag instead of method..
I can't figure out why you would need to do that. Assuming that I fully-understood your question, you are attempting to store something within a model's field that then behaves "dynamically" when rendered.
A model field's content that stores a URL should contain a URL and only a URL by utilizing the URLField.
Else, if you're dynamically building the URL from somewhere else, simply use template markup, i.e. the url template tag as it is meant to be used; it can also take parameters depending on the specific URL pattern. I.e. the url tag is meant to be used in the template's context.
Let me know if you update the question to describe what you are trying to achieve. But storing "behaviour" at data level is something to simply stay away from.

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