Opened 9 years ago

Closed 8 years ago

#2239 closed enhancement (wontfix)

Add a new EthernetAddress Field Type

Reported by: kilian.cavalotti@… Owned by: adrian
Component: Database layer (models, ORM) Version:
Severity: minor Keywords: field type, ethernet address
Cc: kilian.cavalotti@… Triage Stage: Design decision needed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

I often use Ethernet addresses (or MAC addresses) for computer description, in addition to IP addresses. So I think it could be useful to have this kind of field type defined by default. Here comes a patch to add it.

Index: django/db/models/fields/__init__.py
===================================================================
--- django/db/models/fields/__init__.py (revision 3206)
+++ django/db/models/fields/__init__.py (working copy)
@@ -525,6 +525,17 @@
     def validate(self, field_data, all_data):
         validators.isValidEmail(field_data, all_data)

+class EthernetAddressField(Field):
+    def __init__(self, *args, **kwargs):
+        kwargs['maxlength'] = 17
+        Field.__init__(self, *args, **kwargs)
+
+    def get_manipulator_field_objs(self):
+        return [forms.EthernetAddressField]
+
+    def validate(self, field_data, all_data):
+        validators.isValidEthernetAddress(field_data, None)
+
 class FileField(Field):
     def __init__(self, verbose_name=None, name=None, upload_to='', **kwargs):
         self.upload_to = upload_to
Index: django/db/backends/ado_mssql/creation.py
===================================================================
--- django/db/backends/ado_mssql/creation.py    (revision 3206)
+++ django/db/backends/ado_mssql/creation.py    (working copy)
@@ -5,6 +5,7 @@
     'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
     'DateField':         'smalldatetime',
     'DateTimeField':     'smalldatetime',
+    'EthernetAddressField': 'char(17)',
     'FileField':         'varchar(100)',
     'FilePathField':     'varchar(100)',
     'FloatField':        'numeric(%(max_digits)s, %(decimal_places)s)',
Index: django/db/backends/postgresql/creation.py
===================================================================
--- django/db/backends/postgresql/creation.py   (revision 3206)
+++ django/db/backends/postgresql/creation.py   (working copy)
@@ -9,6 +9,7 @@
     'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
     'DateField':         'date',
     'DateTimeField':     'timestamp with time zone',
+    'EthernetAddressField':'varchar(17)',
     'FileField':         'varchar(100)',
     'FilePathField':     'varchar(100)',
     'FloatField':        'numeric(%(max_digits)s, %(decimal_places)s)',
Index: django/db/backends/sqlite3/creation.py
===================================================================
--- django/db/backends/sqlite3/creation.py      (revision 3206)
+++ django/db/backends/sqlite3/creation.py      (working copy)
@@ -8,6 +8,7 @@
     'CommaSeparatedIntegerField':   'varchar(%(maxlength)s)',
     'DateField':                    'date',
     'DateTimeField':                'datetime',
+    'EthernetAddressField':         'char(17)',
     'FileField':                    'varchar(100)',
     'FilePathField':                'varchar(100)',
     'FloatField':                   'numeric(%(max_digits)s, %(decimal_places)s)',
Index: django/db/backends/mysql/creation.py
===================================================================
--- django/db/backends/mysql/creation.py        (revision 3206)
+++ django/db/backends/mysql/creation.py        (working copy)
@@ -9,6 +9,7 @@
     'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
     'DateField':         'date',
     'DateTimeField':     'datetime',
+    'EthernetAddressField':'char(17)',
     'FileField':         'varchar(100)',
     'FilePathField':     'varchar(100)',
     'FloatField':        'numeric(%(max_digits)s, %(decimal_places)s)',
Index: django/db/backends/oracle/creation.py
===================================================================
--- django/db/backends/oracle/creation.py       (revision 3206)
+++ django/db/backends/oracle/creation.py       (working copy)
@@ -5,6 +5,7 @@
     'CommaSeparatedIntegerField': 'varchar2(%(maxlength)s)',
     'DateField':         'date',
     'DateTimeField':     'date',
+    'EthernetAddressField':'char(17)',
     'FileField':         'varchar2(100)',
     'FilePathField':     'varchar2(100)',
     'FloatField':        'number(%(max_digits)s, %(decimal_places)s)',
Index: django/forms/__init__.py
===================================================================
--- django/forms/__init__.py    (revision 3206)
+++ django/forms/__init__.py    (working copy)
@@ -873,6 +873,23 @@
         except validators.ValidationError, e:
             raise validators.CriticalValidationError, e.messages

+class EthernetAddressField(TextField):
+    def __init__(self, field_name, length=17, maxlength=17, is_required=False, validator_list=None):
+        if validator_list is None: validator_list = []
+        validator_list = [self.isValidEthernetAddress] + validator_list
+        TextField.__init__(self, field_name, length=length, maxlength=maxlength,
+            is_required=is_required, validator_list=validator_list)
+
+    def isValidEthernetAddress(self, field_data, all_data):
+        try:
+            validators.isValidEthernetAddress(field_data, all_data)
+        except validators.ValidationError, e:
+            raise validators.CriticalValidationError, e.messages
+
+    def html2python(data):
+        return data or None
+    html2python = staticmethod(html2python)
+
 class IPAddressField(TextField):
     def __init__(self, field_name, length=15, maxlength=15, is_required=False, validator_list=None):
         if validator_list is None: validator_list = []
@@ -890,6 +907,7 @@
         return data or None
     html2python = staticmethod(html2python)

+
 ####################
 # MISCELLANEOUS    #
 ####################
Index: django/core/validators.py
===================================================================
--- django/core/validators.py   (revision 3206)
+++ django/core/validators.py   (working copy)
@@ -24,6 +24,7 @@
     r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
     r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
     r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$', re.IGNORECASE)  # domain
+eth_re = re.compile(r'^[0-9A-F]{2}(:[0-9A-F]{2}){5}$', re.IGNORECASE)
 integer_re = re.compile(r'^-?\d+$')
 ip4_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}$')
 phone_re = re.compile(r'^[A-PR-Y0-9]{3}-[A-PR-Y0-9]{3}-[A-PR-Y0-9]{4}$', re.IGNORECASE)
@@ -101,6 +102,10 @@
     if not ip4_re.search(field_data):
         raise ValidationError, gettext("Please enter a valid IP address.")

+def isValidEthernetAddress(field_data, all_data):
+    if not eth_re.search(field_data):
+        raise ValidationError, gettext("Please enter a valid Ethernet address.")
+
 def isNotEmpty(field_data, all_data):
     if field_data.strip() == '':
         raise ValidationError, gettext("Empty values are not allowed here.")

Change History (5)

comment:1 Changed 9 years ago by anonymous

  • Cc kilian.cavalotti@… added

comment:2 Changed 9 years ago by anonymous

  • Keywords field added; filed removed

comment:3 Changed 9 years ago by adrian

  • priority changed from normal to lowest

comment:4 Changed 9 years ago by SmileyChris

  • Triage Stage changed from Unreviewed to Design decision needed

Do we need/want it?

comment:5 Changed 8 years ago by jacob

  • Resolution set to wontfix
  • Status changed from new to closed

Meh, this is of limited usefulness (and can be done completely stand-alone). Probably best suited for an add-on package.

Note: See TracTickets for help on using tickets.
Back to Top