Django GenericIPAddress field is not validating in

2019-04-16 09:20发布

Hi I have the following Django model

class AccessPointIPAddress(models.Model):
    '''Model for storing AccessPoint IP Addresses.'''
    ap = models.ForeignKey(AccessPoint, related_name='ip_addresses')
    ip_address = models.GenericIPAddressField(protocol='IPv4')
    datetime = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['datetime']
        get_latest_by = 'datetime'

And I am assuming that django's GenericIPAddressField does some string validation that a string is indeed a valid IP Address. I also read django's source and it does have some validation functions tied to GenericIPAddressField

But when I try to run this on django's shell:

# Assume that *ap* is a valid AccessPoint instance
# Notice ip_address IS NOT A VALID IP ADDRESS
>> AccessPointIPAddress.objects.create(ap=ap, ip_address='xxxxxx123123----')
<AccessPointIPAddress: ap xxxxxx123123---- 2015-05-18 12:39:25.491811>

I am expecting that it should raise some kind of ValueError or validation error since the given ip-address xxxxxx123123---- is not a valid ip address.

Am I missing something here? Or is this part of django broken? Currently using Django 1.6.5

1条回答
地球回转人心会变
2楼-- · 2019-04-16 09:52

https://docs.djangoproject.com/en/1.8/ref/validators/#how-validators-are-run

See the form validation for more information on how validators are run in forms, and Validating objects for how they’re run in models. Note that validators will not be run automatically when you save a model, but if you are using a ModelForm, it will run your validators on any fields that are included in your form. See the ModelForm documentation for information on how model validation interacts with forms.

You can override save() method and do a full_clean() on the model instance as described in the docs here: https://docs.djangoproject.com/en/1.8/ref/validators/#how-validators-are-run

or only use validator for GenericIPAddressField:

from django.core.validators import ip_address_validators
from django.core.exceptions import ValidationError

def save(self, *args, **kwargs):
    try:
        ip_address_validators('ipv4', self.ip_address)
    except ValidationError:
        return
    super(AccessPointIPAddress, self).save(*args, **kwargs)

it will use the following validator:

ipv4_re = re.compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$')
validate_ipv4_address = RegexValidator(ipv4_re, _('Enter a valid IPv4 address.'), 'invalid')
查看更多
登录 后发表回答