Marcos
Marcos

Reputation: 844

Exception Value: missing 1 required positional argument

I'd like to get the default value using def/function

Take a look on the snippet code:

models.py

from django.http import HttpRequest

class Contacts(Model):
    def get_client_ip(ip):
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
           ip = x_forwarded_for.split(',')[0]
        else:
           ip = request.META.get('REMOTE_ADDR')
        return ip

    ipaddress = CharField(default=get_client_ip, max_length=20, verbose_name='your IP Address')

makemigrations and migrate executed it without erros or warnings.

When I ran I got the following: Exception Value: get_client_ip() missing 1 required positional argument: 'ip'

Could you please help me on it?

Upvotes: 0

Views: 1718

Answers (2)

sudshekhar
sudshekhar

Reputation: 1666

I don't think you can pass arguments to the default field. The best way I can think of achieving what you want is to override the save function of the model.

Eg:

 class Contacts(models.Model):
     ipaddress = CharField(max_length=20, verbose_name='your IP Address')
     ...
     def save(self):
       if not self.id: #first time saving the model
         self.ip = self.get_client_ip(self.ip)
       super(Contacts, self).save(*args, **kwargs)

EDIT:

Sorry just realized that you're parsing HTTP headers to get the field value. You should set this from the controller directly for your model and use the save function to perform any cleanups that you might need.

Upvotes: 0

ilse2005
ilse2005

Reputation: 11429

There are multiple errors in your code.

Value: get_client_ip() missing 1 required positional argument:

That is because default=get_client_ip calls the function without arguments. Also I don't understand why get_client_ip needs the ip? Just remove that and use @staticmethod

@staticmethod
def get_client_ip():
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
       ip = x_forwarded_for.split(',')[0]
    else:
       ip = request.META.get('REMOTE_ADDR')
    return ip

But this will also not work, because request is not defined in get_client_ip. Request is not visible to Models. The easiest way to fix this is to remove the default and move get_client_ip logic to your view and set the ip field on model creation.

Upvotes: 1

Related Questions