Django Templates - Accessing a M2M attribute and value by name
I am trying to simply access a the values and names of a Many to Many Model in a template by name. Can someone show me what I'm doing wrong.
I have a model called IP. This model can have several attributes. I want to call the "value" of a a particular attribute.
For example: I have an IP Block named Foo. Foo has an attribute "bar" with a value of "good luck".
How can I refer to the named attribute in a M2M and it's value from a template??
This works but YUCK!!
{% for attr in ip.attributes.all %}
{% ifequal attr.attribute.name 'vendor' %}
<td>{{ attr.value }}</td>
{% endifequal %}
{% endfor %}
Thanks so much!!
I have a models.py which looks similar to this.
models.py
VALID_IP_TYPES = (("hard", "Hard IP"),
("soft", "Soft IP"),
("verif", "Verification IP"))
class AttributeType(models.Model):
name = models.CharField(max_length = 32, primary_key = True)
ip_type = models.CharField(max_length = 16, choices = \
tuple(list(VALID_IP_TYPES) + [("all", "All IP")]))
def __unicode__(self):
return u'%s' % (self.name)
class Attribute(models.Model):
attribute = models.ForeignKey(AttributeType)
value开发者_运维技巧 = models.CharField(max_length = 255)
def __unicode__(self):
return u'%s : %s' % (self.attribute, self.value)
class IP(models.Model):
ip_type = models.CharField(max_length = 16, choices = \
tuple(list(VALID_IP_TYPES),
help_text = "Type of IP")
name = models.CharField(max_length = 32, help_text = "Generic Name")
attributes = models.ManyToManyField(Attribute)
def __unicode__(self):
return u'%s' % (self.name)
The relevant views.py
def search(request):
context = RequestContext(request)
if not request.POST:
form = { 'form' : IPSearch() }
return render_to_response('ip_catalog/search.html', form,
context_instance = context)
else:
form = IPSearch(request.POST)
if form.is_valid():
response_dict = {}
cd = form.cleaned_data
ips = ips.filter(**cd)
response_dict.update({'ips':ips})
response_dict.update({'success': True })
return render_to_response('ip_catalog/results.html', response_dict,
context_instance = context)
And finally the template snippet I am struggling with..
{% for ip in ips %}
<tr>
<td>{{ ip.name }}</td>
<td>{{ ip.release_id }}</td>
<td>{{ ip.release_date }}</td>
<!-- THIS WORKS BUT THERE MUST BE A BETTER WAY! -->
{% for attr in ip.attributes.all %}
{% ifequal attr.attribute.name 'vendor' %}
<td>{{ attr.value }}</td>
{% endifequal %}
{% endfor %}
<!-- THIS DOESN'T WORK! -->
<td>{{ ip.attributes.node.value }}</td>
<!-- OR THIS! -->
<td>{{ ip.attribute_id.foundry }}</td>
<!-- OR THIS.. ! -->
<td>{{ ip.attribute.process }}</td>
</tr>
{% endfor %}
Accessing a ManyToManyField
in a model results in a manager, which you can use .filter()
et alia on. Since most of these require at least one argument, you can't call them in a template. Create a template tag instead.
You can't do this well in templates. This is restricted by the design philosophy of Django.
The only way to do this is writing a custom template tag or helper function in model like get_vendor
.
Checkout How do I perform query filtering in django templates
精彩评论