3 changed files with 197 additions and 0 deletions
@ -1 +1,59 @@ |
|||
from django.conf import settings |
|||
|
|||
from netaddr import mac_unix, mac_eui48 |
|||
|
|||
import importlib |
|||
import warnings |
|||
|
|||
class mac_linux(mac_unix): |
|||
"""MAC format with zero-padded all upper-case hex and colon separated""" |
|||
word_fmt = '%.2X' |
|||
|
|||
def default_dialect(eui_obj=None): |
|||
# Check to see if a default dialect class has been specified in settings, |
|||
# using 'module.dialect_cls' string and use importlib and getattr to retrieve dialect class. 'module' is the module and |
|||
# 'dialect_cls' is the class name of the custom dialect. The dialect must either be defined or imported by the module's |
|||
# __init__.py if the module is a package. |
|||
from .fields import MACAddressField # Remove import at v1.4 |
|||
if hasattr(settings, 'MACADDRESS_DEFAULT_DIALECT') and not MACAddressField.dialect: |
|||
module, dialect_cls = settings.MACADDRESS_DEFAULT_DIALECT.split('.') |
|||
dialect = getattr(importlib.import_module(module), dialect_cls, mac_linux) |
|||
return dialect |
|||
else: |
|||
if MACAddressField.dialect: # Remove this "if" statement at v1.4 |
|||
warnings.warn( |
|||
"The set_dialect class method on MACAddressField has been deprecated, in favor of the default_dialect " |
|||
"utility function and settings.MACADDRESS_DEFAULT_DIALECT. See macaddress.__init__.py source or the " |
|||
"project README for more information.", |
|||
DeprecationWarning, |
|||
) |
|||
return MACAddressField.dialect |
|||
if eui_obj: |
|||
return eui_obj.dialect |
|||
else: |
|||
return mac_linux |
|||
|
|||
def format_mac(eui_obj, dialect): |
|||
# Format a EUI instance as a string using the supplied dialect class, allowing custom string classes by |
|||
# passing directly or as a string, a la 'module.dialect_cls', where 'module' is the module and 'dialect_cls' |
|||
# is the class name of the custom dialect. The dialect must either be defined or imported by the module's __init__.py if |
|||
# the module is a package. |
|||
if not isinstance(dialect, mac_eui48): |
|||
if isinstance(dialect, str): |
|||
module, dialect_cls = dialect.split('.') |
|||
dialect = getattr(importlib.import_module(module), dialect_cls) |
|||
eui_obj.dialect = dialect |
|||
return str(eui_obj) |
|||
|
|||
|
|||
from pkg_resources import get_distribution, DistributionNotFound |
|||
import os.path |
|||
|
|||
try: |
|||
_dist = get_distribution('django-macaddress') |
|||
except DistributionNotFound: |
|||
__version__ = 'Please install this project with setup.py' |
|||
else: |
|||
__version__ = _dist.version |
|||
VERSION = __version__ # synonym |
|||
default_app_config = 'abonapp.apps.AbonappConfig' |
|||
@ -0,0 +1,108 @@ |
|||
# |
|||
# I got it on https://github.com/django-macaddress/django-macaddress |
|||
# |
|||
from django.core.exceptions import ValidationError |
|||
from django.db import models |
|||
from netaddr import EUI, AddrFormatError |
|||
from .formfields import MACAddressField as MACAddressFormField |
|||
from . import default_dialect |
|||
import warnings |
|||
|
|||
|
|||
class MACAddressField(models.Field): |
|||
description = "A MAC address validated by netaddr.EUI" |
|||
empty_strings_allowed = False |
|||
dialect = None |
|||
|
|||
def __init__(self, *args, **kwargs): |
|||
self.integer = kwargs.pop('integer', True) |
|||
if not self.integer: # If storing MAC address as string, set max_length to default (17) or use supplied kwarg value. |
|||
kwargs['max_length'] = kwargs.get('max_length', 17) |
|||
super(MACAddressField, self).__init__(*args, **kwargs) |
|||
|
|||
def deconstruct(self): |
|||
''' Django 1.7 migrations require this method |
|||
https://docs.djangoproject.com/en/dev/howto/custom-model-fields/#field-deconstruction |
|||
''' |
|||
name, path, args, kwargs = super(MACAddressField, self).deconstruct() |
|||
kwargs['integer'] = self.integer |
|||
return name, path, args, kwargs |
|||
|
|||
@classmethod |
|||
def set_dialect(cls, new_dialect_clazz): |
|||
''' Setting dialect for EUI (MAC addresses) globally to this Field |
|||
class. |
|||
Class new_dialect_clazz should (finally) extend |
|||
netaddr.strategy.eui48.mac_eui48. |
|||
''' |
|||
warnings.warn( |
|||
"The set_dialect method has been deprecated, in favor of the default_dialect utility function and " |
|||
" settings.MACADDRESS_DEFAULT_DIALECT. See macaddress.__init__.py source or the project README for " |
|||
"more information.", |
|||
DeprecationWarning, |
|||
) |
|||
cls.dialect = new_dialect_clazz |
|||
|
|||
def get_prep_value(self, value): |
|||
if value is None: |
|||
return None |
|||
if not isinstance(value, EUI): |
|||
value = self.to_python(value) |
|||
if self.integer: |
|||
return int(value) |
|||
return str(value) |
|||
value.dialect = default_dialect(self) |
|||
if self.integer: |
|||
return int(value) |
|||
return str(value) |
|||
|
|||
def get_internal_type(self): |
|||
if self.integer: |
|||
return 'BigIntegerField' |
|||
return 'CharField' |
|||
|
|||
def from_db_value(self, value, expression, connection, context): |
|||
return self.to_python(value) |
|||
|
|||
def to_python(self, value): |
|||
if value is None: |
|||
return value |
|||
if isinstance(value, EUI): |
|||
value.dialect = default_dialect(value) |
|||
return value |
|||
try: |
|||
return EUI(value, version=48, dialect=default_dialect()) |
|||
except (TypeError, ValueError, AddrFormatError): |
|||
raise ValidationError( |
|||
"This value must be a valid MAC address.") |
|||
|
|||
def formfield(self, **kwargs): |
|||
defaults = {'form_class': MACAddressFormField} |
|||
defaults.update(kwargs) |
|||
return super(MACAddressField, self).formfield(**defaults) |
|||
|
|||
def get_prep_lookup(self, lookup_type, value): |
|||
# data is stored internally as integer so searching as string |
|||
# yeild 0 result. for example: useful for search in admin. |
|||
if lookup_type in ('exact', 'iexact', 'icontains', 'icontains'): |
|||
try: |
|||
return self.get_prep_value(value) |
|||
except AddrFormatError: |
|||
return None |
|||
elif lookup_type in ('in'): |
|||
try: |
|||
macs = [] |
|||
for mac in value: |
|||
macs += [self.get_prep_value(mac)] |
|||
return macs |
|||
except AddrFormatError: |
|||
return None |
|||
else: |
|||
raise TypeError('Lookup type %r not supported.' % lookup_type) |
|||
|
|||
|
|||
try: |
|||
from south.modelsinspector import add_introspection_rules |
|||
add_introspection_rules([], ["^macaddress\.fields\.MACAddressField"]) |
|||
except ImportError: |
|||
pass |
|||
@ -0,0 +1,31 @@ |
|||
from django.forms import Field |
|||
from django.forms.fields import EMPTY_VALUES |
|||
#"From Django 1.8: The django.forms.util module has been renamed. Use django.forms.utils instead." |
|||
try: |
|||
from django.forms.utils import ValidationError |
|||
except ImportError: |
|||
from django.forms.util import ValidationError |
|||
|
|||
from netaddr import EUI, AddrFormatError |
|||
|
|||
|
|||
class MACAddressField(Field): |
|||
default_error_messages = { |
|||
'invalid': 'Enter a valid MAC Address.', |
|||
} |
|||
|
|||
def clean(self, value): |
|||
""" |
|||
Validates that EUI() can be called on the input. Returns the result |
|||
of EUI(). Returns None for empty values. |
|||
""" |
|||
value = super(MACAddressField, self).clean(value) |
|||
if value in EMPTY_VALUES: |
|||
return None |
|||
try: |
|||
value = EUI(str(value), version=48) |
|||
except (ValueError, TypeError, AddrFormatError): |
|||
raise ValidationError(self.error_messages['invalid']) |
|||
return value |
|||
|
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue