I am trying to implement blog app with django.In home page there will be list of post."post.author.profile.image" is a path to load image from database.If
"post.author.profile.image" is None i need to load an alternative image and if it exist it should load the image from database.So i tried the following code:
def homepage(request):
post= Post.objects.all().order_by('-date')
return render(request,'layout.html',{'posts':post})
layout.html
{% for post in posts %}
<div class="list">
<div class="con">
{% if "post.author.profile.image.url" is None %}
<img src="{% static 'images/b.png' %}" class='logo3'/>
{% else %}
<img src="{{ post.author.profile.image.url }}" class='logo3'/>
{% endif %}
</div>
</div>
{% endfor %}
After running the server if i click on inspect the path in src of image tag is media/None.The code under if is not even running.Whats problem in my code?
How about checking if the image exists?
{% if post.author.profile.image %}
<img src="{{ post.author.profile.image.url }}" class='logo3'/>
{% else %}
<img src="{% static 'images/b.png' %}" class='logo3'/>
{% endif %}
Try this
{% if post.author.profile.image.url %}
<img src="{{ post.author.profile.image.url }}" class='logo3'/>
{% else %}
<img src="{% static 'images/b.png' %}" class='logo3'/>
{% endif %}
Here
{% if "post.author.profile.image.url" is None %}
you're testing if the literal string "post.author.profile.image.url" is None - which it's garanteed to be false, since a literal string is never None.
You want the variable itself:
{% if post.author.profile.image.url is None %}
{% if post.author.profile.image == 'null' %}
<img src="{% static 'images\b.jpg' %}" class="logo3">
{% else %}
<img src="{{post.author.profile.image.url}}" class="logo3">
{% endif %}
I still wonder how this code worked .I tried this before but at that time it was not working may be i would had done some other mistake.But this code is working.
Related
Please Consider the following pieces of code.
<!--templates/home.html-->
{% extends 'base.html' %}
{% load static %}
{% block content %}
{% for post in object_list %}
<div class = 'post-entry'>
<h2><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</h2>
<p>{{ post.body }}</p>
</div>
{% endfor %}
<script type = "text/javascript" src = "{% static 'js/test.js' %}"></script>
{% endblock content %}
and
<!--templates/home.html-->
{% extends 'base.html' %}
{% load static %}
{% block content %}
{% for post in object_list %}
<div class = 'post-entry'>
<h2><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</h2>
<p>{{ post.body }}</p>
</div>
{% endfor %}
{% endblock content %}
<script type = "text/javascript" src = "{% static 'js/test.js' %}"></script>
The first one executes successfully but the second one does not. Is it necessary to load an external static file from inside a django template block and if not then why does the second code not execute?
PS: I am new to django.
For purpose of clarity i am also providing the code for the base template here.
<!--templates/base.html-->
{% load static %}
<html>
<head><title>Django Blog</title>
<link href = "{% static 'css/base.css' %}" rel = "stylesheet">
</head>
<body>
<header><h1>Django Blog</h1></header>
<div>
{% block content %}
{% endblock content %}
</div>
</body>
</html>
The first one executes successfully but the second one does not. Is it necessary to load an external static file from inside a django template block and if not then why does the second code not execute?
If you override a basic template, you can only "fill the blocks" so to speak. Where is Django supposed to write the things you write outside the blocks? At the beginning of the file? At the end of the file? Somewhere in between?
As specified in the documentation on template inheritance [Django-doc]:
The most powerful – and thus the most complex – part of Django’s template engine is template inheritance. Template inheritance allows you to build a base “skeleton” template that contains all the common elements of your site and defines blocks that child templates can override.
You can however define multiple blocks. For example it is common to add a block at the end where you can optionally add some extra JavaScript in, like:
<!--templates/base.html-->
{% load static %}
<html>
<head><title>Django Blog</title>
<link href="{% static 'css/base.css' %}" rel="stylesheet">
</head>
<body>
<header><h1>Django Blog</h1></header>
<div>
{% block content %}
{% endblock content %}
</div>
{% block js %}
{% endblock %}
</body>
</html>
So then you can write the <script ...> part at the bottom of the page, like:
{% extends 'base.html' %}
{% load static %}
{% block content %}
{% for post in object_list %}
<div class='post-entry'>
<h2><a href="{% url 'post_detail' post.pk %}">{{ post.title }}</h2>
<p>{{ post.body }}</p>
</div>
{% endfor %}
{% endblock %}
{% block js %}
<script type="text/javascript" src="{% static 'js/test.js' %}"></script>
{% endblock %}
You can of course define variables, etc. outside the {% block ...%} ... %{ endblock %} parts. But everthing that is rendered outside is ignored if you inherit from a base template.
for the second script, you are specifying the src attribute of the script element using a django command {% static 'js/test.js' %}, for that to work it needs to be inside a django block,
if you want to do this without using the django block, you need to specify the value of the src attribute without using a django commande, you should do it just as if you are working only with html,
<script type = "text/javascript" src = "path_to test.js"></script>
I have two templates that go together, one inside the other. The inner one has an icon that needs to change according to the content of the parent template.
I've tried to pass the icon path using a variable:
src="{% url 'main_bar_icon' %}">
and I added this line of code in the parent template:
{% with main_bar_icon='../static/dist/img/logout-icon.svg' %}
{% include 'main_bar.html' %}
{% endwith %}
So, this is my inner template:
{% block main_bar %}
<a href="">
<img class="app-main-bar-icon"
src="{% url 'main_bar_icon' %}">
</a>
{% endblock main_bar %}
And this is my parent template:
{% block content %}
{% with main_bar_icon='/dist/img/logout-icon.svg' %}
{% include 'main_bar.html' %}
{% endwith %}
{% endblock content%}
In the browser I get this:
<img class="app-main-bar-icon" src(unknown) alt="icon">
Unfortunately, the {% url ... %} templatetag, can be only used to retrieve urls for the views defined in the urlpatterns.
For your needs, you will need either:
use plain variable, since you already assign path to the variable, simply: <img class="app-main-bar-icon" src="{{ main_bar_icon }}">
or, for more future proof solution, you can configure django static files and use {% with main_bar_icon='dist/img/logout-icon.svg' %} and then <img class="app-main-bar-icon" src="{% static main_bar_icon %}">
I am following the book "Django by Example", and right at the beginning of Chapter 3: Extending your blog application, I am trying to load my blog_tags file, however I get this AttributeError:
In template /home/ahmad/Documents/Coding/Django By Example/Excercises/djangoblogapp/mysite/blog/templates/blog/post/list.html, error at line 1
'Library' object has no attribute 'simple'
Here is my base.html:
{% load blog_tags %}
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %} {% endblock %}</title>
<link href="{% static "css/blog.css" %}" rel="stylesheet">
</head>
<body>
<div id = "content">
{% block content %}
{% endblock %}
</div>
<div id = "sidebar">
<h2> My Blog</h2>
<p> This is my blog. I've written {% total_posts %} posts so far. </p>
</div>
</body>
</html>
and my post/list.html:
{% extends "blog/base.html" %}
{% block title %}My Blog {% endblock %}
{% block content %}
<h1> My Blog </h1>
{% if tag %}
<h2>Posts tagged with "{{ tag.name }}"</h2>
{% endif %}
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="tags">
Tags:
{% for tag in post.tags.all %}
<a href="{% url "blog:post_list_by_tag" tag.slug %}">
{{ tag.name }}
</a>
{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
{% include "pagination.html" with page=posts %}
{% endblock %}
Lastly, here is my templatetags/blog_tags.py:
from django import template
register = template.Library()
from ..models import Post
#register.simple._tag(name='useless')
def total_posts():
return Post.published.count()
I have exhausted Google and I cannot find any solution to my problem. I would greatly appreciate your help!
In case it helps, I am using Python 3.6.2 with virtualenvwrapper on a Linux system. Django version is 1.8.6
EDIT: New error that I am getting:
In template /home/ahmad/Documents/Coding/Django By Example/Excercises/djangoblogapp/mysite/blog/templates/blog/base.html, error at line 19
Invalid block tag: 'total_posts'
Basically, the error points towards this line of code:
<p> This is my blog. I've written {% total_posts %} posts so far. </p>
I don't see anything else that could be wrong.
if you want to use simple-tags, remove dot
#register.simple_tag(name='useless')
# ^^^^^
def total_posts():
and edit in the base.html,
replace
written {% total_posts %} posts so far.
<!-- ^^^^^^^^^ -->
to the name of simple tag
written {% useless %} posts so far.
<!-- ^^^^^^^^^ -->
I have the following for loop that spits out all photos in a list:
{% if photos %}
{% for photo in photos %}
{% thumbnail photo.photo "100x100" crop="center" as im %}
<img src="{{ im.url }}" alt="User's photos" data-ajax="{% url 'photo_increase_view' pk=photo.id %}"/>
{% endthumbnail %}
{% endfor %}
{% endif %}
How can edit this to ignore the first result in the list (i.e. display items 2, 3, 4... etc)
Use slice
Replace
{% for photo in photos %}
by
{% for photo in photos|slice:"1:" %}
So , complete code
{% if photos %}
{% for photo in photos|slice:"1:" %}
{% thumbnail photo.photo "100x100" crop="center" as im %}
<img src="{{ im.url }}" alt="User's photos" data-ajax="{% url 'photo_increase_view' pk=photo.id %}"/>
{% endthumbnail %}
{% endfor %}
{% endif %}
Check out forloop.first using Django; for example:
{% if photos %}
{% for photo in photos %}
{% if not forloop.first %}
{% thumbnail photo.photo "100x100" crop="center" as im %}
<img src="{{ im.url }}" alt="User's photos" data-ajax="{% url 'photo_increase_view' pk=photo.id %}"/>
{% endthumbnail %}
{% endif %}
{% endfor %}
{% endif %}
I guess the answer it's a bit late. But a solution is:
{% for photo in photos[1:] %}
.....
{% endfor %}
I have the following code in my template:
{% for object in object_list %}
{% with game=object.game %}
{% for category in object.game.objectmeta.categories.all %}
{% if category.name|title == 'Puzzle' %}
{% if forloop.first %}
<div class='side_header' id='dark_gamelink_side'>
<a class='actionheader' href=""></a>
</div>
{% endif %}
<div class='game_link' id='dark_gamelink'>
<a class='img_link' href="{% url game_view game.id game.title|slugify %}">
<img class='game_img' src='{{game|thumb:"78x65"}}' alt='{{game.title}}' />
</a>
<div class='top_game_title' style='padding:0'>
<a style='position:relative; top:-3px' id='yellowlink' href="{% url game_view game.id game.title|slugify %}">{{game.title}} -- {{category.name|title}}</a>
<img style='position:relative; top:1px; margin-left:12px' src='thumbsup.gif' width='17' height='18'/>
<span style='position:relative; top:-3px; font-size:10px; color:white'>99%</span>
</div>
{% if game.description|length > 65 %}
{{ game.description|slice:"65" }}...
{% else %}
{{ game.description }}
{% endif %}
</div>
{% if forloop.counter0 == 3 %}
<div class='more_games'><br/></div><div class='side_header' id='dark_gamelink_side'><a class='adventureheader' href=adventure.htm></a></div>
{% endif %}
{% endif %}
{%endfor%}
{% endwith %}
{% endfor %}
Now I'm using this:
{% if forloop.first %}
<div class='side_header' id='dark_gamelink_side'>
<a class='actionheader' href=""></a>
</div>
{% endif %}
to try to detect if this is the first iteration of the for loop immediately preceding it not the parent forloop. In other words I'm trying to detect if it's the 1st iteration of this for loop:
{% for category in object.game.objectmeta.categories.all %}
not this one:
{% for object in object_list %}
The way it is now isn't working because it's displaying this:
<div class='side_header' id='dark_gamelink_side'>
<a class='actionheader' href=""></a>
</div>
Twice. How to detect the first iteration of the nested forloop?
Edited:
I have never used these variables but I think forloop.parentloop.first should do it. If not blame me to have misunderstand the Django docs. ;-)
You should check if you are within the parentloop and and then within the first nested node. Please try this modified template. It should you give the right direction.
{% if forloop.parentloop.first %}
I am in the first loop of the parent
{% else %}
{% if forloop.first %}
<div class='side_header' id='dark_gamelink_side'>
<a class='actionheader' href=""></a>
</div>
{% endif %}
{% endif %}
I think the best way to solve this isn't to detect if this is the first iteration in the loop, but rather to write your HTML so that is outside the loop entirely.
You should only be writing HTML elements in the for loop that you actually want repeated for each iteration. If that doesn't work, rethink how you're providing the data to your view (object_list, game, category, etc) so that you can write your markup more easily.
The beginning of your view will probably look something like this:
<div class='side_header' id='dark_gamelink_side'>
<a class='actionheader' href=""></a>
</div>
{% for object in object_list %}
{% with game=object.game %}
{% for category in object.game.objectmeta.categories.all %}
{% if category.name|title == 'Puzzle' %}