Django用户访问日志记录插件:
django_user_visit汉化包
为了给用户显示中文,制作的汉化包,与原来版本区别仅仅是字符串
1:用户不同设备登录时,将会记录
2:用户与之前的ip不相同时,将会记录
3:用户注销,再次登录时,将会记录
4:每隔一天,就算设备与ip相同,但是为当天的首次访问网站,也将记录
原版本为:django-user-visit 2.0
2024年3月11日最新版本
pipy官网
[django-user-visit · PyPI](https://pypi.org/project/django-user-visit/)
gihub网址
[GitHub - yunojuno/django-user-visit: Django app for recording daily user visits](https://github.com/yunojuno/django-user-visit)
pipy
django-user-visit · PyPI
github
GitHub - yunojuno/django-user-visit: Django app for recording daily user visits
支持
>=python3.8版本
django3.2
django4.0
django4.1
django4.2
django5.0
安装过程
pip install django-user-visit
版本
django-user-visit 2.0
添加
INSTALLED_APPS = [
# 添加用户访问记录
'user_visit',
# 写在这个列表最后面就行
]
MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'user_visit.middleware.UserVisitMiddleware', # 这一行
]
执行迁移
python manage.py migrate
(venv) PS C:\Docker\Python\weidanyewu> python manage.py migrate
Operations to perform:
Apply all migrations: admin, api1, auth, captcha, contenttypes, outsourcing, ownorder, sessions, store, user_visit, userprofile
Running migrations:
Applying user_visit.0001_initial... OK
Applying user_visit.0002_add_created_at... OK
Applying user_visit.0003_uservisit_context... OK
Applying user_visit.0004_uservisit_browser_uservisit_device_uservisit_os... OK
下面进行汉化
3:修改【user_visit】包中的models.py文件内容为:
from __future__ import annotations
import datetime
import hashlib
import uuid
from typing import Any
import user_agents
from django.conf import settings
from django.db import models
from django.http import HttpRequest
from django.utils import timezone
from django.utils.translation import gettext_lazy as _lazy
from user_visit.settings import REQUEST_CONTEXT_ENCODER, REQUEST_CONTEXT_EXTRACTOR
def parse_remote_addr(request: HttpRequest) -> str:
"""Extract client IP from request."""
x_forwarded_for = request.headers.get("X-Forwarded-For", "")
if x_forwarded_for:
return x_forwarded_for.split(",")[0]
return request.META.get("REMOTE_ADDR", "")
def parse_ua_string(request: HttpRequest) -> str:
"""Extract client user-agent from request."""
return request.headers.get("User-Agent", "")
class UserVisitManager(models.Manager):
"""Custom model manager for UserVisit objects."""
def build(self, request: HttpRequest, timestamp: datetime.datetime) -> UserVisit:
"""Build a new UserVisit object from a request, without saving it."""
uv = UserVisit(
user=request.user,
timestamp=timestamp,
session_key=request.session.session_key,
remote_addr=parse_remote_addr(request),
ua_string=parse_ua_string(request),
context=REQUEST_CONTEXT_EXTRACTOR(request),
)
uv.hash = uv.md5().hexdigest()
uv.browser = uv.user_agent.get_browser()[:200]
uv.device = uv.user_agent.get_device()[:200]
uv.os = uv.user_agent.get_os()[:200]
return uv
class UserVisit(models.Model):
"""
用户在给定日期访问网站的记录。
这用于跟踪和报告 - 了解网站的访问者数量,并能够报告某人与网站的互动。
我们记录识别用户会话所需的最少信息,以及 IP 和设备的变化。这在识别可疑活动(来自不同位置的多次登录)时很有用。
还有助于识别支持问题(因为在实时聊天中从用户那里获取有用的浏览器数据可能非常困难)。
"""
user = models.ForeignKey(
settings.AUTH_USER_MODEL, related_name="user_visits", on_delete=models.CASCADE,
verbose_name="用户"
)
timestamp = models.DateTimeField(
_lazy("访问时间"),
help_text="记录当天第一次访问的时间",
default=timezone.now,
)
session_key = models.CharField(help_text="Django 会话标识符", max_length=40,)
remote_addr = models.CharField(_lazy("登录地址"),
help_text="客户端 IP 地址(来自 X-Forwarded-For HTTP 标头或REMOTE_ADDR请求属性)",
max_length=100,
blank=True,
)
ua_string = models.TextField(
_lazy("用户代理(原始)"),
help_text=_lazy("Client User-Agent HTTP header"),
blank=True,
)
browser = models.CharField(
_lazy("浏览器"),
max_length=200,
blank=True,
default="",
)
device = models.CharField(
_lazy("设备类型"),
max_length=200,
blank=True,
default="",
)
os = models.CharField(
_lazy("操作系统"),
max_length=200,
blank=True,
default="",
)
uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
hash = models.CharField( # noqa: A003
max_length=32,
help_text=_lazy("从请求属性生成的 MD5 哈希值"),
unique=True,
)
created_at = models.DateTimeField(
_lazy("创建时间"),
help_text= "创建数据库记录的时间 (!=timestamp)",
auto_now_add=True,
)
context = models.JSONField(
default=dict,
blank=True,
null=True,
encoder=REQUEST_CONTEXT_ENCODER,
help_text=_lazy("用于存储临时/临时数据 - 例如GeoIP."),
)
objects = UserVisitManager()
class Meta:
get_latest_by = "timestamp"
verbose_name = '用户访问日志'
verbose_name_plural='用户访问日志'
def __str__(self) -> str:
return f"{self.user} 访问了该网站 {self.timestamp}"
def __repr__(self) -> str:
return f"<UserVisit id={self.id} user_id={self.user_id} date='{self.date}'>"
def save(self, *args: Any, **kwargs: Any) -> None:
"""设置哈希属性并保存对象。"""
self.hash = self.md5().hexdigest()
super().save(*args, **kwargs)
@property
def user_agent(self) -> user_agents.parsers.UserAgent:
"""从原始user_agent字符串中返回 UserAgent 对象。"""
return user_agents.parsers.parse(self.ua_string)
@property
def date(self) -> datetime.date:
"""从时间戳中提取访问日期。"""
return self.timestamp.date()
# see https://github.com/python/typeshed/issues/2928 re. return type
def md5(self) -> hashlib._Hash:
"""生成用于识别重复访问的 MD5 哈希值。"""
h = hashlib.md5(str(self.user.id).encode()) # noqa: S303, S324
h.update(self.date.isoformat().encode())
h.update(self.session_key.encode())
h.update(self.remote_addr.encode())
h.update(self.ua_string.encode())
return h
4:修改【user_visit】包中的app.py文件内容为:
from django.apps import AppConfig
class UserVisitAppConfig(AppConfig):
name = "user_visit"
verbose_name = "用户访问日志"
default_auto_field = "django.db.models.AutoField"