The context variable is empty when displayed in the template. I have tested the query in the Django Shell and the query is returning the data in the Shell.
views.py (https://github.com/josieh/playground-finder/blob/master/playgroundApp/views.py#L11-L26)
def Playground_List(request):
context = {
'playgrounds': Playground.object.all()
}
return render (request, "home.html", context)
Template home.html (https://github.com/josieh/playground-finder/blob/master/playgroundApp/templates/playgroundApp/home.html#L48-L54)
{% for playground in playgrounds %}
{# Each "player" is a player model object. #}
<tr>
<td> {{ playground.Name }}</td>
<td> {{ playground.Address }}</td>
</tr>
{% endfor %}
Can you please help explain why the context variable of playgrounds would be empty?
Thanks for your help!
One problem is that it should be Playground.objects.all(). I imagine that's likely a transcription error in the question text, because that should throw an AttributeError if it was actually what you wrote in your program.
Are you certain your attributes of the Playground model are called Name and Address as opposed to name and address? It is against Python style convention to capitalize the names of attributes. If you have mistakenly capitalized these names then this would indeed cause your output to appear blank.
Injecting print statements/functions (depending on Python 2 or 3) into your view to print the context and/or the QuerySet might help you debug the issue.
Related
I'm trying to access some info with dot notation but I'm getting a weird error. I'll try to explain as well as I can with my code.
My relevant code from views.py file:
def index(request):
// removed "x" assignment as it is long an irrelevant
month = (datetime.datetime.now()).strftime("%B")
year = str(datetime.datetime.now().year)
customers = table(x, month, year)
return render(request, 'index.html', {'customers': customers, "month" : month, "year": year})
Here, I call my tablequery file with table function to return a JSON object of files I have from MONGODB(I am not using MONGODB as the default DB so I do it manually). My table function is as follows:
def table(user, month, year):
///// Code to access DB removed
curs = col.find()
list_curs = list(curs)
liststring = json.dumps(list_curs)
liststring = re.sub("_", "", liststring) // have to remove _ from "_id" because template doesnt allow "_id" type of variable to be used with dot notation
jt = json.loads(liststring)
return jt
Type of "jt" appears to be "list" in python when I print it.
My relevant html code:
<tbody>
{% for customer in customers %}
<tr class="gradeX">
<td>{{ customer.id }}</td>
<td>{{ customer.isim }}</td>
<td>
{% for ekran in customer.ekranlar %}
<li>
{{ ekran }} DENEME
{{ customer.ekranlar.1.hesapbakiyeTL}} TL
{{ customer.ekranlar.1.yurtdisibakiyedolar}} USD
{{ customer.ekranlar.1.yurtdisibakiyeeuro }} Euro
</li>
{% endfor %}
</td>
<td>{{ customer.temsilci }}</td>
<td>
<li>{{ customer.toplambakiyeTL }} TL</li>
<li>{{ customer.toplambakiyeUSD }} USD</li>
<li>{{ customer.toplambakiyeEURO }} EURO</li>
</td>
<td> </td>
<td>
<i class="md md-delete"></i>
<i class="md md-edit"></i>
</td>
</tr>
{% endfor %}
</tbody>
Problem lies within the second for-in loop. When I write "ekran" in customer.ekranlar, I only get the "1", "2", "3" etc as output, but not the values for those. There are more variables within those nested objects(? maybe not objects) but I can only access them if I do "customer.ekranlar.1.hesapbakiyeTL" but when I do "ekran.hesapbakiyeTL"(because I need them looped an printed in table cell) I dont get anything because "ekran" is only "1" or "2" or whatever else the name of the "ekran" is but not the values inside.(I have 4 different accesses as tests to see what is visible how, so it's not the final form)
What I think it should be is like I said, "ekran.hesapbakiyeTL" should be able to access that value, but "ekran" only gets the key, not the nested keys/values inside it. I tried so many different things, tried to change the tablequery output type but I get different problems that way, tried to us "forloop.counter" to use as index to access directly as "customer.ekranlar.forloop.counter" but it appears variables cannot be used in dot notation and many others I've forgotten in the last week. Please, I've been stuck trying to access those values within the for-in loop which stops me from going forward with my project and add other functions.
An example document directly from MongoDB Compass app:
Image for data example
Blues: float numbers
Blacks: strings
There can be more in "ekranlar" as in 1, 2, 3...
All help is appreciated.
Thank you all and have a good day
edit1: I tried to get nested values seperately from python. Same things happens. As soon as I use a second for loop to access like "{{ for ekranlar in customer.ekranlar }}, I only get the key values, not the other variables or their content inside
edit2: How I got around it is that I created a custom tag and sent the customer info to a python file in templatetags with forloop.counter and returned needed info that way. Feels a little clunky but works so meh... If anyone gets around to why this happens inside template html, I'd still love to hear it.
I've passed 'Tango with Django' tutorial but still don't get one thing - why we need to use hidden fields in Django template.
For example, if I have a code
class CategoryForm(forms.ModelForm):
name = forms.CharField(max_length=128, help_text="Please enter the category name.")
views = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
likes = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
Ok, here I get, that views and likes won't be filled by user in form, so they are hidden.
But, in template, inside the form we have something like:
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.help_text }}
{{ field }}
{% endfor %}
Why do we need 2-nd and 3-rd rows? And do we need them?
It's difficult to say exactly why, because the reasons could be pretty numerous.
But broadly speaking, it is probably so that those two fields can be modified or accessed client-side by javascript, and then also be submitted back to the server.
If you're not doing any of that, then you probably don't need them :) But you might have to worry about not overwriting those values when you save changes to the other fields.
Check the generated HTML. Even if hidden, those fields need to be present in the HTML, so that they get sent to the server on form submit. They are "hidden", not "absent".
And, indeed, quite often they are manipulated by the client-side javascript, as well, typically to put a value there.
I am trying to integrate external data in my metatags. What I want to achieve - by entering in Title field (in admin) "Details for {{ product.name }}" I would like to get to get automaticaly "Details for Hadron Collider" as a result in a browser. I have this in my template
{% load seo %}
{% get_metadata for product as metadata %}
{{ metadata.title }}
and I am passing Product object to the template, but what I get as a result is unchanged "Details for {{ product.name }}", so {{ value }} won't be populated / parsed? I have read the docs http://django-seo.readthedocs.org/en/latest/reference/administrators.html, it looks so simple
If you would like to reference the relevant model instance, you type the name of the model surrounded by two braces. For example Buy {{ product }} today!. You can go further and reference different fields from the relevant instance, for example By {{ product.name }} today!.
Though it doesn't work for me. Please, help. Probably I am doing something wrong.
Ok, after days of depression :) I solved it, at least for my project and currently only for Models, but for ModelInstance and Views it's almost I will make it later, it has the same problem in my case. I am quite new to Django, so a better solution may exist, I found this one.
I use Django 1.6.4, Python 2.7, multilingual project (Django Transmeta for model translation)
The problems:
1. variable substitution in models, model instances and views doesn't work. So, if we pass an object to DjangoSEO it won't substitute e.g. {{ product }}, {{ product.name }} variables. According to documentation it should. The problem, for Model is in backends.py, ModelBackend class. Function _resolve_value doesn't pass object to the function _resolve, which is supposed to populate meta tags with object properties. Here are the functions with slight changes that work for me.
def _resolve_value(self, name):
value = super(ModelMetadataBase, self)._resolve_value(name)
try:
return _resolve(value, self._content_object)
except AttributeError:
return value
def _resolve(value, model_instance=None, context=None):
""" Resolves any template references in the given value. """
if isinstance(value, basestring) and "{" in value:
if context is None:
context = Context()
if model_instance is not None:
context[model_instance.__class__.__name__.lower()] = model_instance
t = Template(value)
value = t.render(context)
return value
Also, in the file base.py, function get_linked_metadata we have to attach our object to Metadata instances like this:
if ModelMetadata is not None:
try:
model_md = ModelMetadata.objects.get(_content_type=content_type, _language=language)
except ModelMetadata.DoesNotExist:
model_md = ModelMetadata(_content_type=content_type, _language=language)
model_md._content_object = obj
instances.append(model_md)
And the problem 2 - DjangoSEO was using one Metadata instance for any language, even with option use_i18n = True. So, add _language=language as mentioned above.
Django SEO app is quite good, it has everything SEO needs (if it works :), so there is no reason to reinvent the wheel.
You need to wrap your variables in html tags.
{% load seo %}
{% get_metadata for product as metadata %}
<html>
<head>
<title>{{ metadata.title}}</title>
</head>
<body></body>
</html>
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()
....
I'd like to know how can I add .error class to input elements (to registration app) when the form validation fails.
If you want to place your error CSS class to form input widgets (not their containers), you can derive your form class from the following one:
class StyledErrorForm(forms.Form):
def is_valid(self):
result = super().is_valid()
# loop on *all* fields if key '__all__' found else only on errors:
for x in (self.fields if '__all__' in self.errors else self.errors):
attrs = self.fields[x].widget.attrs
attrs.update({'class': attrs.get('class', '') + ' is-invalid'})
return result
It's now easy -- new feature in Django 1.2
Just add an attribute on the form class & you're good to go. This feature is mentioned in the docs under a "new in 1.2" note, but you can find the magic at django.forms.forms.BoundField.css_classes Here's the API reference, and an example:
class MyForm(forms.Form):
required_css_class = "required"
error_css_class = "error"
This can be done completely through your template.
You build the form template for each form field that you want to test you can use the following example construct
<input type="text" class="reg-txt{% if form.fieldname.errors %} errors{% endif %}"/>
This lets you provide the interface you want without modifying the view & django form code.
Using a Custom Template...
Personally never had much luck using the built in Django error classing solutions, and besides, I like to use the built in 'striptags' template filter on the errors, to get rid of all the html list stuff which I cant figure out how to render nicely anyway.
I use the following custom template to class them as 'error_id'.
#register.filter(is_safe=True)
#stringfilter
def error_id(value):
if value=='':
return ''
else:
return r'<span class="error_id">'+value+'</span>'
Render the individual errors in your template using:
{{ form.my_field.errors|striptags|error_id}}
Or render the whole form using something like:
<table border="1" cellpadding="5px" align="center">
{% for field in form.visible_fields %}
<tr>
<td> {{ field.label_tag }}: </td>
<td> {{ field }} </td>
<td> {{ field.errors|striptags|error_id }} </td>
</tr>
{% endfor %}
</table>
(Better late than never)
You should be able to do this with Django Uni Form