5

I know that if I'm inside of a request function, I can get the user's IP address using ipware.ip's get_ip(request) or other methods, but I'm using a view of (ListView, FormView) so I'm not sure how I would add the IP to the form like I normally would by using:

instance = form.save(commit=False)
instance.ip = get_ip(request)
instance.save()

2 Answers2

3

It's pretty straightforward, use request.META['REMOTE_ADDR'].

instance = form.save(commit=False)
instance.ip = self.request.META['REMOTE_ADDR']
instance.save()

request.META (and request in general) has all kinds of useful information. More information in the docs: https://docs.djangoproject.com/en/1.10/ref/request-response/#django.http.HttpRequest.META

FlipperPA
  • 13,607
  • 4
  • 39
  • 71
  • It gives me an error: NameError at /events/ global name 'request' is not defined –  Dec 05 '16 at 23:35
  • Wups, you're in a CBV, I'll amend my answer - you need to use `self.request`. – FlipperPA Dec 05 '16 at 23:36
  • It didn't give me an error, but the IP isn't saved either. I tried adding self to the get_ip function of ipware and it worked. `from ipware.ip import get_ip` `instance = form.save(commit=False) instance.ip = get_ip(self.request) instance.save()` –  Dec 05 '16 at 23:40
  • Huh, that still has me puzzled, if you're in a generic class based view like FormView. But I'm glad it got it working for you. – FlipperPA Dec 05 '16 at 23:41
3

If you cannot access self.request, here's one way to solve it:

class SignUpForm(forms.ModelForm):
    fullname = forms.CharField(label="Full name", widget=forms.TextInput(attrs={'placeholder': 'Full name', 'class': 'form-control'}))
    class Meta:
        model = SignUps
        fields = ['eventname','fullname','ip']

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None) # Now you use self.request to access request object.
        super(SignUpForm, self).__init__(*args, **kwargs)

    def save(self, commit=True):
        instance =  super(SignUpForm, self).save(commit=False)
        instance.fullname = fullname
        instance.ip = get_ip(self.request)
        if commit:
            instance.save()
        return instance

http://brunobastos.net/how-to-access-the-httprequest-object-in-django-forms/

Apoorv Kansal
  • 3,210
  • 6
  • 27
  • 37
  • `kwargs.pop('request', None)` returns None for me on Django 1.10. I printed kwargs and it doesnt have the request object at all. Did something for Django 1.10? – Anupam Jul 21 '17 at 10:30
  • 1
    It took me a while before I learnt that we need to actually pass the request object from the view for the form to access it. So `mysignupform = SignUpForm(request.POST, request=request)` in `views.py`. See [this](https://stackoverflow.com/questions/1057252/how-do-i-access-the-request-object-or-any-other-variable-in-a-forms-clean-met#comment77436436_1057640) – Anupam Jul 21 '17 at 10:40