Reputation: 37
Trying to store user's IP address when he's sending POST
requests via submitting my form, tried more than a few suggestions on getting the IP address, but didn't manage to make it work properly as I always get null
values stored for the IP in the database table.
I tried using model forms and setting the ip address as a variable inside the form so I can store it more easily into the database using request.META.get
, and x_forwarded_for
to get the actual address from the request in views.py.
My app built as below:
models.py:
class RequestPull(models.Model):
a = models.CharField(max_length=10)
b = models.CharField(max_length=10)
ip_address = models.GenericIPAddressField(null=True)
forms.py:
class GetReq(forms.ModelForm):
class Meta:
model = RequestPull
fields = ['a','b','ip_address']
views.py (one of the attempts that give the same result- null values in the database):
def get_client_ip(request):
remote_address = request.META.get('HTTP_X_FORWARDED_FOR') or request.META.get('REMOTE_ADDR')
ip = remote_address
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
proxies = x_forwarded_for.split(',')
while (len(proxies) > 0 and proxies[0].startswith(PRIVATE_IPS_PREFIX)):
proxies.pop(0)
if len(proxies) > 0:
ip = proxies[0]
print"IP Address",ip
return ip
def reqPull(request):
if request.method == 'GET':
form = GetReq()
else:
form = GetReq(request.POST)
if form.is_valid():
form.ip_address = get_client_ip(request)
form.save()
Expected result is an IP address of the user, as one of the values of the form, to be stored in the database.
Actual result, as said earlier, is valid values for every field in the form but the ip address, which always stored as null
.
Edit. Managed to make it work properly by changing views.py from.
if form.is_valid():
form.ip_address = get_client_ip(request)
form.save()
to.
if form.is_valid():
obj = form.save(commit=False)
obj.ip_address = get_client_ip(request)
obj.save()
and by editing the input field in my template.
Upvotes: 1
Views: 4481
Reputation: 5
Your return ip
statement is indented too far out. Take it back 4 spaces, this should give you your ip addresses. Python function returns None
when no explicit return
statement is given or hit during code execution. Indent according to this:
def get_client_ip(request):
remote_address = request.META.get('HTTP_X_FORWARDED_FOR') or request.META.get('REMOTE_ADDR')
ip = remote_address
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
proxies = x_forwarded_for.split(',')
while (len(proxies) > 0 and proxies[0].startswith(PRIVATE_IPS_PREFIX)):
proxies.pop(0)
if len(proxies) > 0:
ip = proxies[0]
print"IP Address",ip
return ip
Upvotes: 0
Reputation: 37
Managed to make it work properly by changing views.py from.
if form.is_valid():
form.ip_address = get_client_ip(request)
form.save()
to.
if form.is_valid():
obj = form.save(commit=False)
obj.ip_address = get_client_ip(request)
obj.save()
and by editing the input field in my template.
For others who may read this, you should also take note of Kevin's comment, and exclude the ip_address field out of the form entirely instead of using hidden input in the template.
Upvotes: 1