Django 統計網站訪問次數、訪問 ip 、訪問端點及次數
阿新 • • 發佈:2018-12-07
個人部落格:http://www.iamnancy.top
有時候寫完部落格,想知道網站每天的訪問量,都有哪些人訪問,都是來自什麼地方的訪客,都訪問了哪些端點。
效果如下:
編寫 blog/models.py
# 訪問網站的 ip 地址、端點和次數
class UserIP(models.Model):
ip = models.CharField(verbose_name='IP 地址', max_length=30)
ip_addr = models.CharField(verbose_name='IP 地理位置', max_length=30)
end_point = models.CharField(verbose_name='訪問端點', default='/', max_length=30)
count = models.IntegerField(verbose_name='訪問次數', default=0)
class Meta:
verbose_name = '訪問使用者資訊'
verbose_name_plural = verbose_name
def __str__(self):
return self.ip
# 網站總訪問次數
class VisitNumber(models.Model):
count = models.IntegerField(verbose_name='網站訪問總次數', default=0) # 網站訪問總次數
class Meta:
verbose_name = '網站訪問總次數'
verbose_name_plural = verbose_name
def __str__(self):
return str(self.count)
# 單日訪問量統計
class DayNumber(models.Model) :
day = models.DateField(verbose_name='日期', default=timezone.now)
count = models.IntegerField(verbose_name='網站訪問次數', default=0) # 網站訪問總次數
class Meta:
verbose_name = '網站日訪問量統計'
verbose_name_plural = verbose_name
def __str__(self):
return str(self.day)
使用 geoip2 實現 IP 轉換成現實地理位置
安裝 geoip2 庫
pip install geoip2
下載 Maxmind 網站的 IP 資訊庫
地址:http://dev.maxmind.com/geoip/geoip2/geolite2
下載完之後,解壓,將解壓包中的 mmdb 檔案複製到專案的應用程式中 (我的網站是 ‘blog’)。專案結構如下圖所示:
編寫將 IP 轉換為現實地理位置的函式
blog/ip_convert_addr.py
import geoip2.database
def ip_to_addr(ip):
"""
IP 轉換成現實中的地理位置
country = 國家
province = 省
city = 城市
"""
reader = geoip2.database.Reader('blog/GeoLite2-City.mmdb')
response = reader.city(ip)
#print(response)
# 因為有些IP的省份和城市未知,所以設定預設為空
province = ''
city = ''
try:
# 國家、省份、城市
country = response.country.names["zh-CN"]
province = response.subdivisions.most_specific.names["zh-CN"]
city = response.city.names["zh-CN"]
except:
pass
if country != '中國':
return country
if province and city:
if province == city or city in province:
return province
return '%s%s' %(province, city)
elif province and not city:
return province
else:
return country
參考:Python獲取IP的地理位置:經緯度,國家,區域,城市
編寫 blog/visit_info.py
實現更新網站訪問量和訪問 ip 等資訊
from django.utils import timezone
from .models import UserIP, VisitNumber, DayNumber
from .ip_convert_addr import ip_to_addr
# 自定義的函式,不是檢視
def change_info(request, end_point):
"""
# 修改網站訪問量和訪問 ip 等資訊
# 每一次訪問,網站總訪問次數加一
"""
count_nums = VisitNumber.objects.filter(id=1)
if count_nums:
count_nums = count_nums[0]
count_nums.count += 1
else:
count_nums = VisitNumber()
count_nums.count = 1
count_nums.save()
# 記錄訪問 ip 和每個 ip 的次數
if 'HTTP_X_FORWARDED_FOR' in request.META: # 獲取 ip
client_ip = request.META['HTTP_X_FORWARDED_FOR']
client_ip = client_ip.split(",")[0] # 所以這裡是真實的 ip
else:
client_ip = request.META['REMOTE_ADDR'] # 這裡獲得代理 ip
# print(client_ip)
ip_exist = UserIP.objects.filter(ip=str(client_ip), end_point=end_point)
if ip_exist: # 判斷是否存在該 ip
uobj = ip_exist[0]
uobj.count += 1
else:
uobj = UserIP()
uobj.ip = client_ip
uobj.end_point = end_point
try:
uobj.ip_addr = ip_to_addr(client_ip)
except:
uobj.ip_addr = 'unknown'
uobj.count = 1
uobj.save()
# 增加今日訪問次數
date = timezone.now().date()
today = DayNumber.objects.filter(day=date)
if today:
temp = today[0]
temp.count += 1
else:
temp = DayNumber()
temp.dayTime = date
temp.count = 1
temp.save()
將上面的函式匯入到檢視中,在需要時直接呼叫
blog/view.py
...
from .visit_info import change_info
...
def post_detail(request, post_id):
post = get_object_or_404(Post, id=post_id)
post.yueduliang()
change_info(request, '/')
# 記得在頂部引入 markdown 模組
post.body = markdown.markdown(post.body, extensions=['extra', 'codehilite', 'toc',
'tables', 'sane_lists'])
return render(request, 'post_detail.html', context={'post': post})
資料庫遷移
因為我們在 models.py
中建立了 3 個新類,所以需要執行以下命令,以使之作用於資料庫。
$ python manage.py makemigrations
$ python manage.py migrate
之後重啟下伺服器,這樣一個最簡單的頁面訪問量統計就完成了。