Last active
January 3, 2016 04:29
-
-
Save cjlarose/8409714 to your computer and use it in GitHub Desktop.
Django VersionNumberField
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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