开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜