Django:通过信号获取IP地址
我想记录试图登录的用户的IP地址,打算用信号来实现。请问我该怎么做呢?
我已经记录下了登录的时间。
#models.py
class UserLogin(models.Model):
"""user details when logging in"""
user = models.ForeignKey(User)
timestamp = models.DateTimeField(auto_now=True)
这是信号的部分:
#models.py
def user_login_save(sender, instance, **kwargs):
if instance.last_login:
old = instance.__class__.objects.get(pk=instance.pk)
if instance.last_login != old.last_login:
instance.userlogin_set.create(timestamp=instance.last_login)
models.signals.post_save.connect(user_login_save, sender=User)
虽然我知道可以通过:request.META[REMOTE_ADDR]来获取IP地址,但我的问题是我在模型里不能使用request这个实例。我也不太确定从请求中获取信息是否是个好习惯。
那么,有什么推荐的方法吗?
任何回复我都会非常感激。
祝好,
Wenbert
4 个回答
1
这个问题很老了,但我今天遇到了同样的问题,而这是我在谷歌上找到的第一个结果。所以也许这对其他人也有帮助。这就是我解决这个问题的方法。
from django.contrib.auth.signals import (
user_logged_in,
user_logged_out,
user_login_failed,
)
from django.dispatch import receiver
import logging
user_logger = logging.getLogger("user")
@receiver(user_logged_in)
def log_user_login(sender, user, **kwargs):
"""log user "login" to log-file setup in django settings.py"""
# if the IP-ADRESS is 127.0.0.1 from external users then check this
# https://stackoverflow.com/questions/4581789/how-do-i-get-user-ip-address-in-django
request = kwargs["request"]
ip_address = request.META.get("REMOTE_ADDR")
user_logger.info(f"{user} login successful. IP-Address: {ip_address}")
# other functions deleted for brevity
1
因为这个实例在信号中被传递,而这个实例实际上就是保存下来的那个对象,所以你可以在保存的时候把请求对象或者IP地址附加到这个实例上。
user_login.request=request
user_login.save()
然后在信号中可以像这样获取它:
instance.request
1
虽然我知道怎么通过:request.META[REMOTE_ADDR] 获取IP地址,但我的问题是我在模型里不能使用request实例。
这就是为什么你需要视图函数的原因。
我也不太确定从请求中获取东西是否是个好做法。
这是完全可以的。
这就是为什么每个视图函数都会提供请求的原因。
这就是你需要视图函数的原因。
只需在视图函数中处理这些。除非你在写一种新的数据库接口,否则不要去碰信号。