My HTML page won't print my django variable - python

First of all sorry for my bad english but i'm french.
I am currently working on a django app and i'm trying to make my HTML page work but it won't and i dont know why.
I followed the tutoriel but i edited some of the code to fit my purpose. And now my page won't print out my variable.
I have python 2.7.5 and Django 1.11.29
My html page
Now this is my code for the HTML :
{% if True %}
<p> Vrai </p>
<li>{{ Thriller.title }}</li>
{% else %}
<p> faux </p>
{% endif %}
<ul>
<p> Paragraphe : </p>
<li>{{ Thriller.title }}</li>
<li>{{ Thriller.id }}</li>
</ul>
My code for the Django part :
This is in the models.py file :
from django.db import models
import datetime
from django.utils.encoding import python_2_unicode_compatible
from django.utils import timezone
class Artist(models.Model):
name = models.CharField(max_length=200, unique=True)
def __str__(self):
return self.name
class Album(models.Model):
reference = models.IntegerField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
available = models.BooleanField(default=True)
title = models.CharField(max_length=200, unique=True)
picture = models.URLField()
artists = models.ManyToManyField(Artist, related_name='albums', blank=True)
def __str__(self):
return self.title
This is in the views.py file :
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse
from .models import Album, Artist, Contact, Booking
from django.template import loader
def index(request):
albums = Album.objects.order_by('-created_at')
context = {'albums = ': albums}
template = loader.get_template('polls/index.html')
return HttpResponse(template.render(context, request))
This is also my first post here and i dont really know if the post is good or not so forgive it if it's not good !
You can ask me anything you want. Thank's !

You need to call your context variable in the template instead of {{ Thriller.title }} because you did not specify Thriller in the context of your view.
Your context in the index() view:
context = {'albums = ': albums}
Edit this to:
context = {'albums': albums}
and then in your template, for example to loop over all the album titles:
added the if statement:
{% for album in albums %}
{% if album.title == "Thriller" %}
<p>{{ album.title }}</p>
{% endif %}
{% endfor %}

Try this change to your context
context = {'albums': albums}
Then in your template do...
{% for album in albums %}
<p>{{ album.title }}</p>
{% endfor %}

Related

How to access model.field in template? django

I started learning django few days ago and trying to build my first blog.
My problem is that I decided to add an extra field for my categories (subheading), which I want to be in my template, but can't understand how to do it.
my models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=20)
subheading = models.CharField(max_length=160)
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
link = models.TextField()
categories = models.ManyToManyField("Category", related_name="posts")
def __str__(self):
return self.title
views.py
from django.shortcuts import render
from blog.models import Post, Category
def blog_category(request, category):
posts = Post.objects.filter(
categories__name__contains=category
).order_by(
'title'
)
context = {
"category": category,
"posts": posts
}
return render(request, "blog_category.html", context)
The only way category.name or category.subheading are displayed in template (by the teacher) is inside {% for post in posts %} {% endfor %}:
{% for post in posts %}
{% for category in post.categories.all %}
{{ category.subheading }}
{% endfor %}
{% endfor %}
In this case, if there are 10 posts on category page, subheading repeats 10 times. I only need to print 1 to describe category.
Is there a way to call category.subheading outside of {% for post in posts %} ? Or somehow to print only one result.
p.s. sorry for my primitive English level.
You can do this with a Prefetch object [Django-doc]:
from django.db.models import Prefetch
def blog_category(request, category):
posts = Post.objects.filter(
categories__name__contains=category
).prefetch_related(
Prefetch(
'categories',
Category.objects.filter(name__contains=category)
to_attr='relevant_categories'
)
).order_by(
'title'
)
# …
In your template, you can then render this with:
{% for post in posts %}
{% for category in post.relevant_categories %}
{{ category.subheading }}
{% endfor %}
{% endfor %}
Not sure to understand what you want to do but you can search and access to Category elements by doing something like that:
categories=Category.objects.filter(name='NameYouWanttoSearch').values_list('subheading')
can add a model manager to the categories , take single instance and call it in templates instead of all.
class CategoryManager(models.Manager):
def single_category(self):
return self.get_queryset()[:1]
class Category(models.Model):
name = models.CharField(max_length=20)
subheading = models.CharField(max_length=160)
objects = CategoryManager()
def __str__(self):
return self.name
and in templates
{% for post in posts %}
{% for category in post.categories.single_category %}
{{ category.subheading }}
{% endfor %}
{% endfor %}

I am working with Django inclusion_tag and Wagtail Site Setting

I am new in Django and Wagtail and I am facing little problem.
I want to assess Wagtail Site Setting using Django inclusion_tag.
in short, {{ settings.app_1.SimpleHtmlSettings.heading }} and {{ settings.app_1.SimpleHtmlSettings.body }} in index.html is not printing any thing.
I tried total two solutions but non of them is working
app_1_extras.py (simple_html = SimpleHtmlSettings.for_site(context['request'].site))
app_1_extras.py (simple_html = SimpleHtmlSettings.objects.first)
models.py
from django.db import models
from wagtail.contrib.settings.models import BaseSetting, register_setting
# Create your models here.
#register_setting
class SimpleHtmlSettings(BaseSetting):
heading = models.CharField(
max_length=255, help_text='Enter heading')
body = models.CharField(
max_length=255, help_text='Enter body content')
views.py
from django.shortcuts import render
from app_1.models import SimpleHtmlSettings
from django.http import HttpResponse
# Create your views here.
def index(request):
return render(request, 'app_1/test.html')
app_1_extras.py
from django import template
from app_1.models import SimpleHtmlSettings
register = template.Library()
#register.inclusion_tag('app_1/index.html', takes_context=True)
def show_results(context):
# simple_html = SimpleHtmlSettings.for_site(context['request'].site)
simple_html = SimpleHtmlSettings.objects.first
return {'simple_html': simple_html}
index.py
{% load wagtailsettings_tags %}
<h1>{{ settings.app_1.SimpleHtmlSettings.heading }}</h1>
<p>{{ settings.app_1.SimpleHtmlSettings.body }}</p>
<p>Check</p>
test.py
{% load wagtailsettings_tags %}
{% load app_1_extras %}
{% show_results %}
test.html only printing "Check"
Thanks!!!
You're setting up the variable simple_html to be available in your index.html template, and then never using that variable. index.html should become:
<h1>{{ simple_html.heading }}</h1>
<p>{{ simple_html.body }}</p>
<p>Check</p>

Django reverse foreign key relation doesn't work

Hello i am struggling already since 2 days to get a reverse relation going.
I am trying to get pictures of "bilder" into related "doku".
The site returns the {{doku.name}} but nothing from the loop from the related model "bilder"
I tried almost everything i have found on the internet, but maybe I just have overseen something?
here is my models.py:
class Doku(models.Model):
name = models.CharField(max_length=1000)
inhalt = models.TextField(blank=True, null=True)
erstellungsdatum = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name = "Dokumentation"
verbose_name_plural = "Dokumentationen"
def __str__(self):
return self.name
class Bilder(models.Model):
doku = models.ForeignKey(Doku, on_delete=models.CASCADE)
name = models.CharField(max_length=1000)
bilder = models.ImageField(upload_to="bilder/doku/")
def __str__(self):
return self.name
my views.py
#login_required(login_url='login')
def Dokus(request):
doku = Doku.objects.all()
context = {'doku':doku}
return render(request, "doku/index.html", context)
and my template:
{% for doku in doku %}
{{ doku.name }}
{{ doku.bilder.name }}
{% for bilder in doku.bilder_set.all %}
<img src="{{ bilder.bilder.url }}">
<p>{{ bilder.name }}</p>
{% endfor %}
{% endfor %}
EDIT: here's my urls.py:
from django.urls import path
from . import views
from django.contrib.auth import views as auth_views
app_name = "apps"
urlpatterns = [
path('doku/', views.Dokus, name="Doku"),
path('doku/create', views.DokuCreate.as_view(), name="DokuCreate"),
path('doku/detail/<int:pk>', views.DokuDetail.as_view(), name="DokuDetail"),
path('doku/update/<int:pk>', views.DokuUpdate.as_view(), name="DokuUpdate"),
path('doku/delete/<int:pk>', views.DokuDelete.as_view(), name="DokuDelete"),
path('doku/picadd', views.BilderCreate.as_view(), name="DokuBilderCreate"),
]
{{ doku.bilder.name }} isn't going to work. Remove that.
Similarly, {{dokubilder.dokubilder.url}} isn't going to work because there is no dokubilder in your template context.
For the models you have posted, looping through {% for bilder in doku.bilder_set.all %} in your template should work. If it doesn't, you'll need to provide more information about how to reproduce the problem.
I would suggest that you use different variable names for the instance and the queryset, e.g. {% for doku in docku_list %}. If you change it to docku_list, remember to update your view.
{% for doku in dokus %}
{{ doku.name }}
{% for bilder in doku.bilder_set.all %}
<p>{{ bilder.name }}</p>
{% endfor %}
{% endfor %}

Django comments not showing in template

I have a system setup to show comments on a post detail page, however the comments are not showing. I have been focusing on the template tags, because I have used this view code elsewhere and it has worked, however I may be wrong. No errors returning, just not showing the comment in the detail view.
userpost_detail.html:
{% extends 'base.html' %}
{% block content %}
<div class="main">
<h1 class="posttitle">{{ userpost.title }}</h1>
<p class="postcontent">{{ userpost.post_body }}</p>
{% if request.user.is_authenticated and request.user == post.author %}
<a class="link" href="{% url 'feed:edit_post' post.id %}">Edit Post</a>
{% endif %}
Add Comment
{% for comment in userpost.usercomment.all %}
{% if user.is_authenticated %}
{{ comment.create_date }}
<!--
<a class="btn btn-warning" href="{% url 'comment_remove' pk=comment.pk %}">
<span class="glyphicon glyphicon-remove"></span>
</a>
-->
<p>{{ comment.comment_body }}</p>
<p>Posted By: {{ comment.author }}</p>
{% endif %}
{% empty %}
<p>No Comments</p>
{% endfor %}
</div>
{% include 'feed/sidebar.html' %}
{% endblock %}
app PostDetailView:
class PostDetailView(DetailView):
model = UserPost
app add_comment_to_post view:
#login_required
def add_comment_to_post(request,pk):
post = get_object_or_404(UserPost,pk=pk)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.author = request.user
comment.save()
return redirect('feed:post_detail', pk=post.pk)
else:
form = CommentForm()
return render(request,'feed/comment_form.html',{'form':form})
app urls:
from django.conf.urls import url
from feed import views
app_name = 'feed'
urlpatterns = [
url(r'^new/$',views.CreatePostView.as_view(),name='new_post'),
url(r'^post/(?P<pk>\d+)$',views.PostDetailView.as_view(),name='post_detail'),
url(r'^post/(?P<pk>\d+)/edit/$',views.UpdatePostView.as_view(),name='edit_post'),
url(r'^post/(?P<pk>\d+)/delete/$',views.DeletePostView.as_view(),name='delete_post'),
url(r'^post/(?P<pk>\d+)/comment/$',views.add_comment_to_post,name='add_comment'),
]
Models.py:
from django.db import models
from django.core.urlresolvers import reverse
from django.conf import settings
from django.contrib.auth import get_user_model
User = get_user_model()
# Create your models here.
class UserPost(models.Model):
author = models.ForeignKey(User,related_name='userpost',null=True)
post_date = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=150,blank=False)
post_body = models.TextField(max_length=1000,blank=False)
def publish(self):
self.save()
def get_absolute_url(self):
return reverse('index')
def __str__(self):
return self.title
class UserComment(models.Model):
post = models.ForeignKey('feed.UserPost',related_name='comments')
author = models.ForeignKey(User,related_name='usercomment')
comment_date = models.DateTimeField(auto_now_add=True)
comment_body = models.TextField(max_length=500)
def publish(self):
self.save()
def get_absolute_url(self):
return reverse("userpost_list")
def __str__(self):
return self.comment_body
As #user6731765 mentioned you need comments coz of related_name
{% for comment in userpost.comments.all %}
When you get comment_remove error
You need to define a url for comment_remove and define a view for that.
urlpatterns = [
. . . . . .
url(r'^comment/remove/(?P<pk>\d+)/$',views.DeleteCommentView.as_view(),name='comment_remove'),
]
Then in views.py
class DeleteCommentView(DeleteView):
model=UserComment
Due to the related_name you are using for posts in UserComment, try using
{% for comment in userpost.comments.all %}
in your template instead.

django categories: How to get children of a category using django-categories?

I am using django-categories to implement music related app. I want artist as my category and his/her songs as children
models.py
from django.db import models
from django_extensions.db.fields import AutoSlugField
from categories.models import CategoryBase
class Artist(CategoryBase):
cat = models.CharField(max_length=255, blank=True)
def __unicode__(self):
return self.name
class Song(models.Model):
title = models.CharField(max_length=255,)
slug = AutoSlugField(populate_from='title', unique=True)
description = models.TextField()
cat = models.ForeignKey(Artist, blank=True)
def __unicode__(self):
return self.title
In templates, artist_details.html
{% extends 'base_post.html' %}
{% load category_tags %}
{% block page_content %}
<h1>{{ artist.name }}</h1>
{% if artist.children.count %}
<h2>Subcategories</h2>
<ul>
{% for child in artist.children.all %}
<li>{{ child }}</li>
{% endfor %}
</ul>
{% endif %}
The template is getting rendered coz I can see artist's name. But i am unable to fetch the children. I checked the docs but I could not find much stuff related to fetching children.
There is data for both models in my DB, I added relevant info via admin interface. Can anyone tell me what I am missing ?
Also I open to using better packages. You can give any suggestions that implements categories.
SOLUTION: From django docs https://docs.djangoproject.com/en/1.6/topics/templates/#accessing-method-calls
thanks mariodev
Even using django-categories, you can't have songs as children of artists. Artists just do not form a category.
What you instead want is something like this:
from django.db import models
from django_extensions.db.fields import AutoSlugField
from categories.models import CategoryBase
class MusicCategory(CategoryBase):
# add extra fields, like images, "featured" and such here
pass
class Artist(CategoryBase):
name = CharField(max_length=255,)
categories = models.ManyToManyField(MusicCategory, related_name="artists")
def __unicode__(self):
return self.name
class Song(models.Model):
slug = AutoSlugField(populate_from='title', unique=True)
title = models.CharField(max_length=255,)
artist = models.ForeignKey(Artist, related_name="songs", on_delete=models.PROTECT)
categories = models.ManyToManyField(MusicCategory, related_name="songs")
description = models.TextField()
def __unicode__(self):
return self.title
and with some templates
{% extends 'base_post.html' %}
{% load category_tags %}
{% block page_content %}
<h1>{{ artist.name }}</h1>
{% if artist.songs.all.exists %}
<h2>Songs</h2>
<ul>
{% for song in artist.songs.all %}
<li>{{ song }}</li>
{% endfor %}
</ul>
{% endif %}
REF: https://django-categories.readthedocs.org/en/latest/custom_categories.html#creating-custom-categories

Categories