'Django save user IP each new Sign In

Each time the user logs in, I want to store the IP address in a list of the respective user, so that each user has a list with all IP addresses used during login.

How could I do this?

Custom User Model

class NewUser(AbstractBaseUser, PermissionsMixin):

    email = models.EmailField(_('E-Mail'), unique=True)
    username = models.CharField(max_length=150, unique=True)
    start_date = models.DateTimeField(default=timezone.now)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(default=timezone.now)
    code = models.ImageField(blank=True, upload_to='code')

    objects = CustomAccountManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username', ]

Views SingIn

def signin_view(request):

    if request.user.is_authenticated:
        return HttpResponseRedirect('/')

    form = SigninForm(request.POST or None)
    if form.is_valid():
        time.sleep(2)
        email = form.cleaned_data.get("email")
        password = form.cleaned_data.get("password")
        user = authenticate(request, email=email, password=password)
        if user != None:
            login(request, user)
            return redirect("/dashboard/")
        else:
            request.session['invalid_user'] = 1 
    return render(request, "signin.html", {'form': form})

I know how to get the IP but I want to know how I save it in something like a list



Solution 1:[1]

The user IP address is stored within the request object. You can access it in this way:

request.META.get("REMOTE_ADDR")

If you are using PostgreSQL as your database you can use a JSONField or an ArrayField. PostgreSQL specific fields

I have never used an ArrayField but I think for this particular use case it would be more indicated than a JSONField, unless you want to store some additional information about each user's IP address.

So let's proceed:

# Step 1: Add an ArrayField of CharFields to your NewUser model

from django.contrib.postgres.fields import ArrayField

class NewUser(AbstractBaseUser, PermissionsMixin):
    ...
    ip_address_list = ArrayField(models.CharField(max_length=15))
    ...

# Step 2: Refactor your view 

# Here i made a little function to store the IP address because
# I had to run it twice
def store_ip_address(request):
    new_user = request.user
    new_user.ip_address_list.append(request.META.get('REMOTE_ADDR'))
    new_user.save()

def signin_view(request):

    if request.user.is_authenticated:
        store_ip_address(request) ### New ###
        return HttpResponseRedirect('/')

    form = SigninForm(request.POST or None)
    if form.is_valid():
        time.sleep(2)
        email = form.cleaned_data.get("email")
        password = form.cleaned_data.get("password")
        user = authenticate(request, email=email, password=password)
        if user != None:
            login(request, user)
            store_ip_address(request) ### New ###
            return redirect("/dashboard/")
        else:
            request.session['invalid_user'] = 1 
    return render(request, "signin.html", {'form': form})

I haven't tested this, let me know if it doesn't work

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1