Django GenericIPAddress 字段不验证输入

Django GenericIPAddress field is not validating input

您好,我有以下 Django 模型

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'

我假设 django 的 GenericIPAddressField 会进行一些字符串验证,以确保字符串确实是有效的 IP 地址。我还阅读了 django 的源代码,它确实有一些与 GenericIPAddressField

相关的验证函数

但是当我在 Django 的 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>

我预计它会引发某种 ValueError 或验证错误,因为给定的 ip 地址 xxxxxx123123---- 不是有效的 ip 地址。

我是不是漏掉了什么?或者 django 的这一部分坏了?目前使用 Django 1.6.5

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.

您可以覆盖 save() 方法并对模型实例执行 full_clean() ,如文档中所述: https://docs.djangoproject.com/en/1.8/ref/validators/#how-validators-are-run

或仅对 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)

它将使用以下验证器:

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')

已接受的答案对我不起作用;所以我查看了验证器的源代码并找到了这些函数:

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


ip = "127.0.0.1"

try:
    validate_ipv46_address(ip) # Success
except ValidationError:
    print("Invalid")

也适用于其他类型:

validate_ipv4_address(ip)
validate_ipv6_address(ip)