个人博客: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)
pip install geoip2
地址:http://dev.maxmind.com/geoip/geoip2/geolite2
下载完之后,解压,将解压包中的 mmdb 文件复制到项目的应用程序中 (我的网站是 ‘blog’)。项目结构如下图所示:
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
之后重启下服务器,这样一个最简单的页面访问量统计就完成了。
django统计网站访问次数,同时记录访问ip地址和次数
Python获取IP的地理位置:经纬度,国家,区域,城市