Skip to content

Instantly share code, notes, and snippets.

@cjlarose
Last active January 3, 2016 04:29
Show Gist options
  • Save cjlarose/8409714 to your computer and use it in GitHub Desktop.
Save cjlarose/8409714 to your computer and use it in GitHub Desktop.
Django VersionNumberField
import struct
from django.db import models
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^core\.fields\.version_number\.VersionNumberField"])
class VersionNumber(object):
def __init__(self, major, minor=0, patch=0, build=0):
self.number = (int(major), int(minor), int(patch), int(build))
def __str__(self):
"""
Pretty printing of version number; doesn't print 0's on the end
"""
end_index = 0
for index, part in enumerate(self.number):
if part != 0:
end_index = index
return ".".join([str(i) for i in self.number[:end_index+1]])
class VersionNumberField(models.Field):
"""
A version number. Stored as a integer. Retrieved as a VersionNumber. Like
magic. Major, minor, patch, build must not exceed 255
"""
__metaclass__ = models.SubfieldBase
def get_internal_type(self):
return 'IntegerField'
def to_python(self, value):
"""
Convert a int to a VersionNumber
"""
if value is None:
return None
if isinstance(value, VersionNumber):
return value
if isinstance(value, tuple):
return VersionNumber(*value)
part_bytes = struct.pack(">I", value)
part_ints = [ord(i) for i in part_bytes]
return VersionNumber(*part_ints)
def get_prep_value(self, value):
"""
Convert a VersionNumber or tuple to an int
"""
if isinstance(value, tuple):
value = VersionNumber(*value)
if isinstance(value, int):
return value
major, minor, patch, build = value.number
return major << 24 | minor << 16 | patch << 8 | build
def value_to_string(self, obj):
value = self._get_value_from_obj(obj)
return self.get_db_prep_value(value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment