Ip to country for Django comments (2 years ago)

Thursday, 17 August 2006, 22:10 p.m.
Tags: { django programming python }

The day i saw these little flags near people comments, i could not wait to implement this in my django project.

What you need

  • The ip-to-country data file, 60k entries as a csv file here.
  • A set of tiny flags images, some kind there which you will put in /media/img/flags/ of your project.

Then we can start looking at your django project by firstly creating a new iptocountry application >python manage.py startapp iptocountry

Models

Then we edit the models.py file, we need to make the fields match the ip-to-country.csv data file, and to add a method to import this data from cvs to your project database iptocountry_iptocountry table.

from django.db import models

# ip-to-country
class IpToCountry(models.Model):
    IP_FROM = models.PositiveIntegerField()
    IP_TO = models.PositiveIntegerField()
    COUNTRY_CODE2 = models.CharField(maxlength = 2)
    COUNTRY_CODE3 = models.CharField(maxlength = 3)
    COUNTRY_NAME = models.CharField(maxlength = 50)     

class Admin:
    ordering = ['IP_FROM']   

def __str__(self):
    return "%s %s %s" % (self.IP_FROM ,self.IP_TO, self.COUNTRY_NAME) 

def import_csv(self, file):
    import csv
        # First delete all the objects before inserting
    IpToCountry.objects.all().delete()
            # create a reader to get the data from the file
    reader = csv.reader(open(file))
    count = 0    
    for ipf, ipt, cc2, cc3, cname in reader:
        count += 1          
        object = IpToCountry(count,ipf, ipt, cc2, cc3, cname)
        object.save()
        if count % 10000 == 0:
            print count
    print count , "inserted. :)"
    del reader

We can now install the application, first edit your settings.py and add 'your_project.iptocountry', to INSTALLED_APPS.

Import data

Then we need to actualy import the data by running import_csv, to do this get to the python shell python manage.py shell and enter the following commands which just call the wanted method.

from coulix_org.iptocountry.models import IpToCountry
iptc = IpToCountry()
iptc.import_csv('/your/file/path/ip-to-country.csv')

After few seconds you should see the first "10 000" showing, wait few minutes for the process to complete.

Filters

All of this is quite fun so far, but how do we use this for our comments ? Well, comments have an ip field by default, we will use this ip to map to a country name and get the appropriate flag. To do we need some custom filtering, which given an ip returns a path to the image.

If you have look at the ip-to-country.csv data, you can see it uses a strange way of storing ip values, it is called longip notation, we therefore need a method to convert our normal ip from the comment object to the long ip representation in our database.

Let's start this by creating a *templatetags folder in our iptocountry application folder, add an empty init.py* file to it and create a iptocountry_filter.py file wich contains :

from django import template
register = template.Library()

def ip2long(ip):
    ip_array = ip.split('.')
    ip_long = int(ip_array[0]) * 16777216 + int(ip_array[1]) * 65536 + int(ip_array[2]) * 256 + int(ip_array[3])
    return ip_long

def get_country2(value, arg):
    ''' arg is the location of the flag imgs, eg '/media/img/flag/' '''
    from coulix_org.iptocountry.models import IpToCountry
    value = ip2long(value)
    try:
        # ip of comment has to be in a range of an ip-to-country object IP_FROM and IP_TO
        iptc = IpToCountry.objects.get(IP_FROM__lte=value, IP_TO__gte=value)
    except IpToCountry.DoesNotExist:
        return " "
    return "<img src='" + arg + (iptc.COUNTRY_CODE2).lower() + ".png' alt='" + (iptc.COUNTRY_NAME).lower() + "' />"

register.filter('get_country2', get_country2)

Restart your server for the new filters to be accessible.

Templates

We are finaly set, let's use it in your template after getting the list of comments, and the flag should appears (well if you are trying it with an ip of 127.0.0.1 nothing will happens, try to edit the ip in the django admin).

{% load iptocountry_filter %}
{% for comment in comment_list %}
[...]
    {{ comment.ip_address|get_country2:"/media/img/flag/"}}
[...]
{% endfor %}

Comments

  1. Aug 20 2006
    australia
    #1

    I spotted a pylon version resulting from this post : btbytes there nice :).

  2. Aug 20 2006
    india
    #2

    Grégory, Thanks for the cool idea:) Working with Pylons is a lot of fun.

  3. Aug 21 2006
    france
    #3

    Testing... :)

  4. Aug 22 2006
    france
    #4

    Thanks for sharing this cool tips!

    Also testing ;-)

  5. Aug 22 2006
    australia
    #5

    pas de problemes :), la traduction francaise arrivera bientot.

  6. Aug 22 2006
    brazil
    #6

    Hi. I bet people comment just to see the new flags. I did :)

  7. Aug 22 2006
    canada
    #7

    I did too, nice blog :-)

  8. Aug 23 2006
    france
    #8

    hey nice stuff

  9. Aug 24 2006
    china
    #9

    only test!

  10. Aug 24 2006
    united states
    #10

    another test

  11. Aug 25 2006
    honduras
    #11

    testing

  12. Aug 25 2006
    poland
    #12

    yet another test (yat)

  13. Aug 25 2006
    australia
    #13

    no worries guys, all the flag are there haha

  14. Aug 25 2006
    netherlands
    #14

    I wanna see the dutch flag :)

  15. Aug 29 2006
    singapore
    #15

    singapore?

  16. Aug 29 2006
    china
    #16

    test it ok!

  17. Aug 29 2006
    czech republic
    #17

    Thanks for cool tip.
    One question: way do you have:
    del reader
    on the end of import_csv method? I thought, that python have garbage collector, so after end of this method, reference count will be 0, and reader will be deleted automaticaly. Am I wrong?

  18. Aug 29 2006
    australia
    #18

    True its useless. :)

  19. Aug 29 2006
    czech republic
    #19

    I've just tried this tutorial, using Postgresql database, unfortunately it doesn't work in Postgresql, because Postgresql have no Positive Integer type, so range is only to about 0 - 2,000,000,000 (0 - 2^31), which is not enough for IP adresses (2^32). And what is worse, there is no BigIntegerField type in django (svn version). I found patch on django source site, but it's old and unapplicable for current version of django. There is one more patch for big integer on that page, but only for MySQL :(. I don't understand, how could django be without such a base thing like big integer?

  20. Aug 29 2006
    australia
    #20

    Hum true that's a problem Postgresql has a big integer type ? then maybe we could ask the dev to do something about it. check irc #django. And show us your website when you are done :)

  21. Aug 30 2006
    czech republic
    #21

    If you read that page, you will see, that there was patch for BigIntegerField type for django ONE YEAR ago - and developers didn't applied it to project. Nowadays, structure of django sources was chang so that patch is inapplicable.

    Second patch is only few days old, but only for MySQL, and if there will be no patch for other databases, I'm sure that developers don't use it.

    And about my website: I've just come through "Writing your first Django app" tutorial, and found your site when I was looking for example apps in django. So my django site is quite far away ;).

  22. Aug 30 2006
    sweden
    #22

    Thank you for cool idea!

  23. Sep 5 2006
    hungary
    #23

    My countryflag here too

  24. Sep 6 2006
    italy
    #24

    italy

  25. Sep 7 2006
    latvia
    #25

    Latvia?

  26. Sep 13 2006
    poland
    #26

    poland plz

  27. Sep 13 2006
    romania
    #27

    romania :)

  28. Sep 13 2006
    sweden
    #28

    Sweden!

  29. Sep 14 2006
    india
    #29

    india

  30. Sep 15 2006
    norway
    #30

    Thanks! very cool :)

    Norway!

  31. Sep 15 2006
    argentina
    #31

    argentina! lol very cool, will use someday in some project ;D

  32. Sep 16 2006
    belgium
    #32

    Belgium (hopefully)

  33. Sep 17 2006
    germany
    #33

    and germany, too..

  34. Sep 20 2006
    netherlands
    #34

    netherlands

  35. Sep 21 2006
    canada
    #35

    Québec!

  36. Sep 23 2006
    bulgaria
    #36

    Bulgaria

  37. Sep 27 2006
    new zealand
    #37

    New Zealand

  38. Sep 27 2006
    serbia and montenegro
    #38

    Checking Serbia

  39. Sep 28 2006
    austria
    #39

    Austria

  40. Sep 29 2006
    japan
    #40

    from Japan. GeoIP?

  41. Sep 29 2006
    greece
    #41

    greece?

  42. Oct 4 2006
    trinidad and tobago
    #42

    this is cool dude.. keep up the good work

  43. Oct 6 2006
    ukraine
    #43

    Ukraine?

  44. Oct 11 2006
    germany
    #44

    Yeah! Germany!

  45. Oct 12 2006
    india
    #45

    yeah baby

  46. Oct 12 2006
    united states
    #46

    checkin' the flag

  47. Oct 12 2006
    uruguay
    #47

    Just love my flag... lets see if it works... (I's UY by the way)

  48. Oct 14 2006
    switzerland
    #48

    Now we can't have he swiss flag missing can we? :)

  49. Oct 18 2006
    spain
    #49

    Euskadi (Basque Country)

  50. Oct 21 2006
    switzerland
    #50

    Switzerland

  51. Oct 21 2006
    brazil
    #51

    brazil ?

  52. Oct 23 2006
    france
    #52

    france

  53. Oct 26 2006
    russian federation
    #53

    russia

  54. Oct 30 2006
    china
    #54

    seems not geoip? similar one

  55. Nov 8 2006
    republic of korea
    #55

    Korea?

  56. Nov 9 2006
    #56

    South Africa?

  57. Nov 20 2006
    finland
    #57

    This is nice! :)

    PS. Finland!

  58. Nov 21 2006
    dominican republic
    #58

    Dominican Republic

  59. Nov 24 2006
    indonesia
    #59

    my country

  60. Nov 27 2006
    #60

    Kenya? Cool!

  61. Nov 27 2006
    australia
    #61

    oups no kenya :) i should update the db

  62. Dec 16 2006
    colombia
    #62

    What about the sunny Barranquilla, Colombia?

  63. Dec 20 2006
    canada
    #63

    test

  64. Dec 20 2006
    brazil
    #64

    From Brazil... :P

  65. Dec 25 2006
    switzerland
    #65

    From Switzerland

  66. Dec 25 2006
    republic of korea
    #66

    Here's the cute Korean flag again :)

    Merry Christmas, my love! Isn't there NC regional flag???

  67. Dec 29 2006
    poland
    #67

    PL

  68. Dec 29 2006
    united kingdom
    #68

    UK

  69. Dec 30 2006
    india
    #69

    Sounds Very nice!

  70. Jan 5 2007
    uruguay
    #70

    Uruguay

  71. Jan 7 2007
    chile
    #71

    CHILE!

  72. Jan 10 2007
    united kingdom
    #72

    UK!

  73. Jan 12 2007
    united states
    #73

    Mongolia!

  74. Jan 12 2007
    united states
    #74

    Ok, i was lying about mongolia.

  75. Jan 12 2007
    united states
    #75

    Looks like your missing kenya and south africa

  76. Jan 12 2007
    united states
    #76

    Right NOW: 8:13 UTC (whats up with your time?)

  77. Jan 13 2007
    turkey
    #77

    turkey?

  78. Jan 16 2007
    bangladesh
    #78

    Bangladesh?

  79. Jan 16 2007
    iceland
    #79

    Iceland?

  80. Jan 22 2007
    finland
    #80

    Seems nice idea, but why the CAPITALIZED variable names in model, they're not constants, right.

  81. Jan 22 2007
    germany
    #81

    test

  82. Feb 1 2007
    spain
    #82

    ¿con eñes?

  83. Feb 1 2007
    austria
    #83

    sitting in the heart of europe

  84. Feb 19 2007
    australia
    #84

    Australia

  85. Feb 25 2007
    china
    #85

    China?

  86. Feb 25 2007
    italy
    #86

    uh

  87. Mar 17 2007
    philippines
    #87

    Pilipinas

  88. Mar 30 2007
    #88

    russia

  89. Apr 2 2007
    australia
    #89

    hum there is a bug in the comments numbering, i guess it increments the number including the spams which are not shown :/.

  90. Apr 8 2007
    united states
    #90

    USA again!

  91. Apr 9 2007
    australia
    #91

    interesting i wanna see

  92. Apr 16 2007
    australia
    #92

    Just a Testing :P

  93. Apr 16 2007
    australia
    #93

    Quite a few Aussies... so here's another :)

  94. Apr 19 2007
    italy
    #94

    Yet another spaghetti-eater :)

  95. Apr 21 2007
    thailand
    #95

    From Thailand

  96. Apr 27 2007
    united kingdom
    #96

    Has anyone's flag turned out wrong in this list? I was just thinking about asking the user to supply their country as a way of preventing spam bot attacks.

  97. Apr 27 2007
    united kingdom
    #97

    Testing again. Nice idea!

  98. Apr 28 2007
    turkey
    #98

    Türkiye

  99. May 16 2007
    united states
    #99

    Testing.

  100. May 17 2007
    australia
    #100

    Very Nice

  101. May 23 2007
    #101

    Nigeria?

  102. May 24 2007
    singapore
    #102

    uniquely

  103. May 24 2007
    singapore
    #103

    Post #114 got hijacked.

  104. May 24 2007
    australia
    #104

    havent fixed the comments counter yet :/

  105. Jun 4 2007
    canada
    #105

    test

  106. Jun 6 2007
    canada
    #106

    Testing also (should be canada!)

  107. Jun 6 2007
    china
    #107

    chinese

  108. Jun 10 2007
    ukraine
    #108

    ukraine

  109. Jun 13 2007
    hong kong
    #109

    HK

  110. Jun 21 2007
    china
    #110

    china,wuhan The flags images is gif format now

  111. Jul 3 2007
    united kingdom
    #111

    test

  112. Jul 13 2007
    poland
    #112

    test2

  113. Jul 17 2007
    united states
    #113

    just had to do it

  114. Jul 19 2007
    #114

    Make it #130. Hope you are not running out of tab

  115. Aug 4 2007
    italy
    #115

    Hi all from Italy! :)

  116. Aug 15 2007
    spain
    #116

    test!

  117. Aug 15 2007
    china
    #117

    Hi! Good site respect! home depot canada Visit home depot canada Thanks!

  118. Aug 29 2007
    united states
    #118

    Testing US

  119. Sep 4 2007
    #119

    test123

  120. Sep 5 2007
    singapore
    #120

    test

  121. Sep 7 2007
    ireland
    #121

    testing again...

  122. Sep 7 2007
    germany
    #122

    test

  123. Sep 15 2007
    thailand
    #123

    test

  124. Oct 26 2007
    armenia
    #124

    armenia?

  125. Nov 7 2007
    republic of moldova
    #125

    tara Moldova

  126. Nov 27 2007
    canada
    #126

    Canada, Alberta

  127. Dec 28 2007
    china
    #127

    China

  128. Jan 2 2008
    india
    #128

    bharat :)

  129. Jan 11 2008
    latvia
    #129

    test

  130. Jan 11 2008
    austria
    #130

    Home

  131. Jan 15 2008
    united states
    #131

    Dog Acres, USA

  132. Jan 18 2008
    #132

    Holger Danske

  133. Jan 18 2008
    #133

    Hmm, it seems that my danish work IP isn't registered, better try it at home too.

  134. Jan 20 2008
    denmark
    #134

    Trying from my home ADSL.

  135. Feb 8 2008
    japan
    #135

    From Japan!!

  136. Feb 19 2008
    taiwan
    #136

    Taiwan

  137. Feb 24 2008
    #137

    from morocco

  138. Mar 2 2008
    poland
    #138

    poland :)

  139. Mar 22 2008
    #139

    Thanks!

  140. Mar 26 2008
    china
    #140

    test

  141. Apr 2 2008
    malaysia
    #141

    testing

  142. Apr 7 2008
    canada
    #142

    Canada

  143. Apr 21 2008
    spain
    #143

    Spain

  144. Apr 24 2008
    canada
    #144

    testing

  145. May 9 2008
    spain
    #145

    Spain

  146. May 21 2008
    #146

    Works from Russia

  147. May 23 2008
    slovenia
    #147

    Seems like I'm the first from Slovenia.

    Cool project! :-)

  148. May 29 2008
    india
    #148

    Nice one..

  149. Jun 13 2008
    new zealand
    #149

    testing

  150. Jun 18 2008
    #150

    test

  151. Jul 14 2008
    china
    #151

    cool!

  152. Aug 1 2008
    russian federation
    #152

    Test from Russia

  153. Aug 9 2008
    brazil
    #162

    Brazil

Post yours


Tag Cloud

Archives

Last Comments

Rss Feeds