I developed a custom tag to look up the country of a certain IP address using an IP to country database. It's sort of rough and ready, but it should work. The idea is that you read the comment.ip_address, feed it to the {% country %} tag, which then spits out the two letter country code. The interesting thing is that the tag works once and only once per page load if it has to render a variable. All subsequent calls raise template.VariableDoesNotExist in the code below.
The interesting thing is that if you strip out the ability to recognize an IP as a string and make it just render variables, and you bind self.ip as a Variable object in the __init__ method and then try to call its render method in the CountryNode's render method, it actually raises AttributeError and claims that Variable object has no attribute render. Weird! FYI, I'm using Django 1.2. Anyone have any thoughts about what the heck is going on? Here's the Python code: from django import template from django.template import Variable, Template from django.db import connection register = template.Library() class CountryNode(template.Node): def __init__(self, ip): self.ip = ip def __repr__(self): return "<CountryNode>" def render(self, context): if self.ip[0] in '\'"': self.ip = self.ip.strip('\'"') else: try: self.ip = Variable(self.ip).resolve(context) except template.VariableDoesNotExist: return '' octets = [int(octet) for octet in self.ip.split('.')] decimal_ip = octets[0] * 256**3 + octets[1] * 256**2 + octets[2] * 256 + octets[3] cursor = connection.cursor() cursor.execute("SELECT ctry FROM iptocountry WHERE ip_from <= '%(decimal_ip)d' AND ip_to >='%(decimal_ip)d'" % {'decimal_ip':decimal_ip}) try: ctry = cursor.fetchone()[0] except TypeError: ctry = "" cursor.close() return ctry @register.tag('country') def do_country(parser, token): """ {% country [ip] %} [ip] is a variable or string which is an IP address. The tag attempts to look up the IP in the ip_to_country database table, and if successful, the tag is replaced with the two letter ISO code for the country. """ try: bits = token.split_contents() return CountryNode(bits[1]) except IndexError: raise template.TemplateSyntaxError, "country tag requires one argument." And here's the piece of template: <table class="comment_table"> {% for comment in comments.object_list %} <tr> <td class="checkbox"> <input type="checkbox" name="comment_number" value="{{ comment.id }}" /> </td> <td class="comment"> <div class="comment_field"> <span class="comment_field_name">Content Item:</span> <a href="{{ comment.content_object.get_absolute_url }}">{{ comment.content_object }} </a> </div> <div class="comment_field"> <span class="comment_field_name">By:</ span> {{ comment.user_name }}{% if comment.user_url %} - <a href="{{ comment.user_url }}">Website</a>{% endif %}{% if comment.user_email %} - <a href="mailto: {{ comment.user_email }}">Email</a>{% endif %} </div> <div class="comment_field"> <span class="comment_field_name">From IP:</ span> {{ comment.ip_address }} ({% country comment.ip_address %}) </div> </td> </tr> {% endfor %} </table> -- You received this message because you are subscribed to the Google Groups "Django users" group. To post to this group, send email to django-users@googlegroups.com. To unsubscribe from this group, send email to django-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-users?hl=en.