I am having an issue with templating system in Django, I am doing a Movie list app just to learn more about Django and I have already declared my models like following:
class Pelicula (models.Model):
nombre = models.CharField(max_length = 30)
genero = models.CharField(max_length = 20)
año = models.IntegerField()
def __str__(self):
return self.nombre
Then I have declared my view like following
def index(request):
pelicula = Pelicula.objects.all()
return render_to_response("index.html", dict(pelicula = pelicula, usuario = request.user))
So as far as i know, I am not having any trouble here
Then the problem starts on my template
<!DOCTYPE html>
<html>
<head>
<title>Mis peliculas favoritas</title>
</head>
<body>
<h1>Mis peliculas favoritas</h1>
<ol>
{% for pelicula in pelicula.object_list %}
<li>{{ pelicula.nombre }}</li>
{% endfor %}
</ol>
agregar pelicula nueva
</body>
</html>
So as you see, I am using a for loop to get all the objects in my db, I have 3, but when i run the server, the title shows up and the other link bellow named "agregar" shows up except for the movies, I am wondering if the problem is something between the "pelicula" name instead of using Pelicula as i used on declaring my model, anyway I have also changed that to Pelicula.object_list and it didn't worked anyway
I believe I am having a trouble understanding how to use the information i have through Django template tags
Thanks in advance and please forgive my grammar as I am not a native english speaker
In the view code you have pelicula = Pelicula.objects.all() which creates a list of all the abjects from the database. You then send this to the template with the same name, which means all you have to do in the template is iterate over them. Try changing the template to this:
<h1>Mis peliculas favoritas</h1>
{% if pelicula %}
<ol>
{% for item in pelicula %}
<li>{{ item.nombre }}</li>
{% endfor %}
</ol>
{% else %}
didn't find any...
{% endif %}
Part of the confusion seems to come from the fact that the template code and the view code is separate. The template doesn't know anything about the view code. The context dictionary just sets the names that can be used in the template and in the template the only names that you have available to use are the ones that you passed to it via the dictionary. The names in the view and template here are the same in this case because you set them to be the same. They aren't the same variables though, they just have the same name. In the template pelicula is already a list of objects so you don't need to do anything extra to use it in the template loop.
Related
I'm trying to create a website for students and professors which includes a database of courses. Each course is a model Kurs which includes among other fields the following ones, which are the professor running the course and the name of the course:
prowadzacy = models.ForeignKey(User)
nazwa = models.CharField(max_length=200)
In the shell, I can easily find all courses ran by a given professor:
>>> Kurs.objects.filter(prowadzacy__username='stefantestowy')
<QuerySet [<Kurs: Estetyka 7>]>
So in the above I learn that the professor with the username 'stefantestowy' runs one course, 'Estetyka 7'.
After a professor logs in (I'm using the built-in Django login mechanism) he or she is redirected to usersite.html, which should display information about the professor, including the list of names of the courses he or she is running. But if I want to crudely use the syntax which works in the shell to produce an HTML list, I encounter a 'cannot parse' error. Namely, my usersite.html contains the following:
Your login is {{request.user.username}} </br>
Your name is {{request.user.first_name}} {{request.user.last_name}} </br>
(...)
Here is a list of your courses: </br>
<ul>
{% for kurs in Kurs.objects.filter(prowadzacy__username=request.user.username) %}
<li>{{ kurs.nazwa }}</li>
{% endfor %}
</ul>
which leads to the following error:
Could not parse the remainder: '(prowadzacy__username=request.user.username)' from 'Kurs.objects.filter(prowadzacy__username=request.user.username)'
Just to be sure, I changed
prowadzacy__username=request.user.username
to
prowadzacy__username='stefantestowy'
that is, the name successfully used in the shell, but the 'could not parse' error persists. What am I doing wrong?
Additional detail, if it could be of any help: settings.py contains
LOGIN_REDIRECT_URL = '/polls/usersite'
urls.py's urlpatterns contains
url(r'^usersite/$', views.userviewbasic, name='usersite'),
and the relevant view in views.py is just the minimal
def userviewbasic(request):
return render(request, 'polls/usersite.html')
Thanks in advance!
{% for kurs in Kurs.objects.filter(prowadzacy__username=request.user.username) %}
<li>{{ kurs.nazwa }}</li>
{% endfor %}
This won't work in a template.
You will need to pass the filtered list to the template like so.
def userviewbasic(request):
kurs = Kurs.objects.filter(prowadzacy__username=request.user.username)
return render(request, 'polls/usersite.html', {"kurs": kurs})
And iterate over the parameter kurs in the template.
{% for kur in kurs %}
<li>{{ kur.nazwa }}</li>
{% endfor %}
You can read more about the template language in Django here: https://docs.djangoproject.com/en/1.10/ref/templates/api/#rendering-a-context
I want to loop data taken from database in rendered template. Using cms plugin.
I dont have problem looping data in html template. But if i use CMSPlugin to insert new app in placeholder, nothing shows.
If i run url localhost:port/test.html.I got input what i want. But rendered template doesnt loop data.
{% for post in posts %}
{{ post.firstoption }}
{% endfor %}
if I use code below, nothing shows in my rendered template. Values are passed in rendered template. Because, if i try {{instance.firstoption}} i get value shown in template. Problem is i cant loop data with tag instance.
{% for post in instance.posts %}
{{ post.firstoption }}
{% endfor %}
I also tried {% for post in instance.posts_set.all %}
and {% for post in instance.posts.all %}
cms_plugins.py
class pricing(CMSPluginBase):
model = mymodel
name = _("myplugin")
render_template = "template.html"
cache = False
def render(self, context, instance, placeholder):
context.update({'instance': instance})
return context
models.py
class mymodel(CMSPlugin):
firstoption = models.CharField(max_length=200)
def __str__(self):
return self.firstoption
It is probably because you need to call all on your posts
{% for post in instance.posts.all %}
{{ post.firstoption }}
{% endfor }
I am developing an application with Django framework and I'm new to it
I need to create a query that simply joins 2 tables( type and subType ) and then later on use the result in the views the models file looks like this:
class Type(models.Model):
name = models.CharField(max_length=60)
description = models.CharField(max_length=200)
class SubType(models.Model):
name = models.CharField(max_length=60)
description = models.CharField(max_length = 200)
Type = models.ForeignKey(Type)
And in home.html file I have : (I dropped out the bootstrap code to make it more readable )
<ul>
<li ><a href="/home" >Home Page</a></li>
{% for type in all_types %}
<li >
{{ type.name }}
<ul >
--The Inner Loop--
</ul>
</li>
{% endfor %}
</ul>
I need to create an list of types and then inside each type I need to create another list which contains the subTypes of each type
I have no idea how do I have to create the query inside the views.py
def index(request):
list_all_types = #Here I have to create a join query via django models
t = loader.get_template('home.html');
c = Context({
'all_types' : list_all_types,
});
return HttpResponse(t.render(c));
So please let me know how do I have to make the query and replace the correct code with the comment part in views.py and what changes do I have to add to make to the home.html to make it enabled show all the subTypes instead of --inner loop in home.html
Thanks in advance
You don't need to do anything in the view other than get the types:
types = Type.objects.all()
In the template, you just iterate over type.subtype_set.all:
<ul>
{% for subtype in type.subtype_set.all %}
<li>{{ subtype.name }}</li>
{% endfor %}
</ul>
Note that this is well covered by the tutorial. (As is the use of the render shortcut rather than loading and rendering the template separately.)
(Actually, what I said at first was not quite true: for the sake of efficiency, you can add prefetch_related() to the Type query.)
I'm trying to build a website that has products and categories.
When you are on the page of a product, you can click a button to see a list of all the categories it falls under.
You can click another button, that appears on all pages, to see a list of all the categories overall.
In the html page see_all_categories, I wrote a simple block like this:
{% extends 'base.html' %}
{% load staticfiles %}
{% block content%}
{{Category.all}}
{% endblock content %}
I expect to see a messy printout of all the categories but I don't. It doesn't return an error, but it produces nothing, other than the base.html.
What am I doing wrong?
You want to display a list of the categories. I assume your Category model owns an attribute named "title" which is the representation of your Category.
If you're using Django template engine or Jinja2, you can make a for loop inside your template like this :
{% for cat in Category.objects.all %}
{{ cat.title }}
{% endfor %}
As a troubleshooting, I'd suggest you didn't pass your Category model to your template, that is not done automatically. You have to add your model to the context before rendering the template.
As mentionned in the comments, here is doc for template rendering with Django templates.
Django Template Guide
To add your model to the context you can follow this guide.
I don't intend to help you further because I lack of information and that may vary a LOT according to your settings. (Class Based views ? Function based views ? What kind of template are you using... And so on)
I figured out the solution after many long annoying hours of trying everything. I feel dumb but I want to spare the next guy the massive pain in the two-pack.
This is what I did:
In the Views.py, I changed the view function for this page FROM this:
def view_all_categories(request):
context = {'Category' : Category}
return render(request, 'store/see_all_categories.html', context)
TO this
def view_all_categories(request):
all_cats = Category.objects.all().order_by('id')
context = {'all_categories' : all_cats}
return render(request, 'store/see_all_categories.html', context)
and in the page see_all_categories.html itself, I changed it (from the question) TO this:
{% extends 'base.html' %}
{% load staticfiles %}
{% block content%}
{% for cat in all_categories %}
<p>{{ cat.name }}</p>
{% endfor %}
{% endblock content %}
And now it works!!
I am hitting a brick wall when it comes to solving this problem. I have a template that is being included in an other template, but I am unable to render any template variables in the included template. I have a separate template tag file for the included template. I am at a total loss right now how to resolve this problem.
I would like to be able to render the field values from my model in the template (which consist of an image, a short description, etc.) I am fairly certain that I am going about this in the wrong way.
Below is my code:
The model:
class AddOnItem(models.Model):
base_product = models.ForeignKey(Product)
base_price = models.DecimalField(max_digits=8, decimal_places=2, default=0.0)
addon_image = models.ImageField(upload_to='uploads/shop/product/images/',
default='uploads/shop/product/images/', help_text='Max width: 450px')
short_description = models.CharField(max_length=255, blank=True)
def __unicode__(self):
return self.base_product.name
The template:
{% load addon_tags %}
{% if items_to_add %}
{% for items in items_to_add %}
<div id="addon-container">
<div id="left-addon" class="addon-container">
<img src="#" class="addon-image">
<p class="addon-description">{{items.short_description}}</p>
</div>
</div>
{% endfor %}
{% endif %}
addon_tags.py:
from django import template
from sho.models import AddOnItem
register = template.Library()
#register.inclusion_tag("foo/templates/v/sho/addon.html", takes_context=True)
def add_on_render():
context['items_to_add'] = AddOnItem()
return context
I imagine I am doing either a lot wrong (my assumption at the moment) or I am missing some minor bit. I have been working on this for several days and have gone over the docs repeatedly. I am simply completely missing something and this has become a major blocker for me. Any help would be appreciated.
Django version 1.4
Edit:
I ended up rewriting the view and did away with the templatetag. Thanks to both Daniel Roseman and Odif Yltsaeb for their replies.
1) From your post you are adding empty, new item into the context in add_on_render templateag.
2) I cant see in your post, WHERE you are using {% add_on_render %} templatetag. You have created templattag, but do not seem to be using it anywhere.
It is bit hard to understand what exactly are you trying to do or why you even need templatetag there.
If you want to display models field value, you do not need templateag for this and all the stuff that you show in your "template" part of this post, could be very well in your main template, which i assume, is not shown in your post.
If you want to use templatetag, then this templatetag should probably recieve AddOnItem istance as parameter like this:
#register.inclusion_tag("foo/templates/v/sho/addon.html", takes_context=True)
def add_on_render(item):
context['items_to_add'] = item
return context
And You could use it in some template like this:
{% load addon_tags %}
{% if items_to_add %}
{% for items in items_to_add %}
<div id="addon-container">
<div id="left-addon" class="addon-container">
<img src="#" class="addon-image">
<p class="addon-description">{% add_on_render items %}</p>
</div>
</div>
{% endfor %}
{% endif %}
and your foo/templates/v/sho/addon.html
would like like this:
{{ items_to_add.short_description }}
But doing it this way seems very unnecessary as you could achieve all that without templatag by using the template code that you already have outside your "main" template.
You haven't posted the template that you are attempting to include the tag in. I suspect you're not calling it at all, because there are a couple of errors that would cause exceptions if you did try and use the tag. You need to do {% add_on_render %} somewhere in your main template.
As I say though there are a couple of errors. Firstly, you don't define context (as an empty dict) before adding the items_to_add key. You can shortcut this by just doing it in one go.
Secondly you've made items_to_add a single, blank, AddOnItem. So in your included template, iterating through items_to_add does nothing at all. Not sure what you are trying to do there. Perhaps you want to pass all AddOnItem instances?
context = {'items_to_add': AddOnItem.objects.all()}
Or maybe you want to filter them by some criteria, in which case you probably want to pass those criteria to the inclusion tag itself:
def add_on_render(product):
context = {'items_to_add': AddOnItem.objects.filter(base_product=product)}
and you would call it from the main template like this:
{% add_on_render my_product %}
if you set "takes_context=True" you should take context as the first argument in decorated function:
#register.inclusion_tag("foo/templates/v/sho/addon.html", takes_context=True)
def add_on_render(context):
context['items_to_add'] = AddOnItem()
....