I have a formset. I want to extract out the id of the model object that each form in the set represents.
This is because I plan to use a template tag to pass this id to a function and return a related object.
How can I do this?
{% for each in model_formset %}
{{each.instance.id}}
{% endfor %}
Related
I´m trying to use foreign key values in a template.
When I try to show it, I get the value on screen correctly.
{% for x in dataset %}
<p> {{ x.fieldname }}
{% endfor %}
But when I try to use it for comparisons it uses the id, not the value.
{% for x in dataset %}
{% if x.fieldname == "The name I want" %}
<p> {{ x.fieldname }}
{% endif %}
{% endfor %}
I´ve been looking some posts relateing serializers with this, but (in my little knowledge) I understand serializers are to send or receive data from outside the application.
As the is only tu use the values within the application, is there another way to get the actual value for comparisons? Should I use the serializers approach?
Thanks!
I think you assume too much "magic" here. If you fetch the attribute that is related to a ForeignKey, it simply fetches the related instance. Now in case you render such instance, Django will typically fallback on the __str__ of the model instance.
So what you need to do is find out how the __str__ of the model that is referenced works. For example if Model uses the .name attribute to convert it to a string, you can write:
{% if x.fieldname.name == "The name I want" %}
In case it is unknown how it is rendered, you can use the stringformat template filter:
{% if x.fieldname|stringformat:"" == "The name I want" %}
In Django templates, we use the filter on value fields such as {{value | formatvalue}}
I want to generate my form dynamically like the example below.
{% for field in form %}
{{ field }}
{% endfor %}
As you know, the field attribute will be generated as an html element. Is there a way to add a filter to a field value?
Thanks in advance.
How can I access an attribute of an object using a variable? I have something like this:
{% for inscrito in inscritos %}
{% for field in list_fields_inscrito %}
{{inscrito.field}} //here is the problem
{% endfor %}
{% endfor %}
For example Inscrito have: inscrito.id, inscrito.Name and inscrito.Adress and I only want to print inscrito.id and inscrito.Name because id and Name are in the list_fields_inscrito.
Does anybody know how do this?
You can write a template filter for that:
myapp/templatetags/myapp_tags.py
from django import template
register = template.Library()
#register.filter
def get_obj_attr(obj, attr):
return getattr(obj, attr)
Then in template you can use it like this:
{% load myapp_tags %}
{% for inscrito in inscritos %}
{% for field in list_fields_inscrito %}
{{ inscrito|get_obj_attr:field }}
{% endfor %}
{% endfor %}
You can read more about writing custom template tags.
Fixed answer for non string attributes
The selected answer don't cover cases where you need to access non string attributes.
If you are trying to access an attribute that isn't a string, then you must use this code:
from django import template
register = template.Library()
#register.filter
def get_obj_attr(obj, attr):
return obj[attr]
For this, create a folder named templatetags on your app's folder, then create a python file with whatever name you want and paste the code above
inside.
Inside your template load your brand new filter using the {% load YOUR_FILE_NAME %}, be sure to change YOUR_FILE_NAME to your actual file name.
Now, on your template you can access the object attribute by using the code bellow:
{{ PUT_THE_NAME_OF_YOUR_OBJECT_HERE|get_obj_attr:PUT_THE_ATTRIBUTE_YOU_WANT_TO_ACCESS_HERE }}
How pass a user parameter for example:
{% for document in documents %}
{% for status in document.status_for user %}
{{status}}
{% endfor %}
{% endfor %}
Generate A Exception:
Exception Type: TemplateSyntaxError Exception Value: 'for' statements
should use the format 'for x in y': for status in
document.status_for user
Easy Way for this?
EDIT:
Forgot one small detail, This is in the Loop!
You need to manipulate your data before sending it to the template.
# views.py
# ... inside view
statuses = list()
for document in documents:
statuses.append( document.status_for(request.user) )
return render_to_response('path/to/template.html', {'statuses': statuses}, context_instance=RequestContext(request))
And in your template:
{% for status in statuses %}
{{ status }}
{% endfor %}
From django template Variables and lookups
A variable can only be called if it has no required arguments. Otherwise, the system will return an empty string.
If you really want to do this, you can write custom template filter or tag.
Or marshal the data in view appropriately then pass to template.
You can create a custom template tags :
// In your app_folder/templatetags/custom_filter.py
#register.filter
def user_status(status, user):
// Do work on these values
And use it in your view
{% for status in document.status_for %}
{{status|user_status(user)}}
{% endfor %}
You can find more informations about custom template tags in Django, here
If I have a list of objects that require similar layouts but need some attribute set based on the class of object how can I go about getting the class name while class and other xx values are not available within templates.
{% for obj in objects %}
<div class={{obj.__class__.__name__}}
..
</div>
{% endfor }}
There is probably an alternative approach i'm missing here..
You can also write a custom filter. My use case was to check whether or not an html element in a Django form was a checkbox. This code has been tested with Django 1.4.
I followed the instructions about Custom Filters. My filter code looks as such.
In myapp/templatetags/class_tag.py:
from django import template
register = template.Library()
#register.filter(name='get_class')
def get_class(value):
return value.__class__.__name__
In your template file:
{% load class_tag %}
{% if Object|get_class == 'AClassName' %}
do something
{% endif %}
{{ Object|get_class }}
A little dirty solution
If objects is a QuerySet that belong to a model, you can add a custom method to your model.
class mymodel(models.Model):
foo = models........
def get_cname(self):
class_name = ....
return class_name
then in your template you can try:
{% for obj in objects %}
<div class="{{obj.get_cname}}">
..
</div>
{% endfor }}
a bit simpler; assuming your layout is a list of a single model:
class ObjectListView(ListView):
model = Person
template_name = 'object_list.html'
def model_name(self):
return self.model._meta.verbose_name
Then in object_list.html:
{% for obj in object_list %}
<div class="{{view.model_name}}">...</div>
{% endfor }}
David's suggestion of a custom filter is great if you need this for several classes.
The Django docs neglect to mention that the dev server won't detect new templatetags automatically, however, so until I restarted it by hand I was stuck with a TemplateSyntaxError class_tag is not a registered tag library.
.