保存后访问Django自定义模型字段(非主要BigAutoField)的值

时间:2011-11-03 12:32:42

标签: django django-models autofield

我的一个模型中有Django自定义字段“BigAutoField”。这不是主键。我使用uuid作为我的主键。 插入时,一切正常。我在mysql数据库中获得一个新条目,该字段的自动递增值。但问题是在保存模型实例后无法获取此字段的值。 (点符号不起作用)。我必须再次获取对象实例以访问其值。 谁能帮助我如何在不重新加载的情况下访问该值?


class BigAutoField(models.PositiveIntegerField):
__metaclass__ = models.SubfieldBase

def __init__(self, *args, **kwargs):
    self.sequence_name = kwargs.pop('sequence_name', None)
    kwargs['blank'] = True
    kwargs['editable'] = False
    kwargs['null'] = False
    kwargs['unique'] = True
    super(BigAutoField, self).__init__(*args, **kwargs)

def db_type(self, connection):
    engine = settings.DATABASE_ENGINE
    if engine[-5:] == 'mysql':
        return 'bigint AUTO_INCREMENT'
    elif engine == 'oracle':
        return 'NUMBER(19)'
    elif engine[:8] == 'postgres':
        return 'bigserial'
    else:
        raise NotImplemented()

def get_internal_type(self):
    return 'BigAutoField'

def to_python(self, value):
    if value is None:
        return value
    try:
        return long(value)
    except (TypeError, ValueError):
        raise exceptions.ValidationError(
                _("This value must be a long integer."))

def get_db_prep_value(self, value, connection=None, prepared=False):
    if value is None:
        return value
    return long(value)

这是我的自定义bigautofield类。我第一次使用这个字段对模型进行保存时效果很好。

    x= XYZ.objects.create(a='a',b='b')
    x.save()

但是现在我无法访问x.c,其中c是XYZ中的BigAutoField。虽然在mysql数据库中可以看到相同的自动增量值。

1 个答案:

答案 0 :(得分:0)

我特别要求在表格中将uuid作为主键,将1字段作为autofield。由于django不允许自动对象而不是主键我必须从正整数字段继承它。为了解决这个问题,我必须实现预保存功能。这将从mysql db获取下一个自动增量键并在插入之前设置属性值。通过这种方式,我的值现在可以正确保存,我也可以访问它们。

 def pre_save(self, model_instance, add):
    if self.sequence_name is None:
        self.sequence_name = '%s' % (model_instance._meta.db_table)
    old_val = getattr(model_instance, self.attname)
    if add and old_val is None:
        cursor = connection.cursor()
        cursor.execute("SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = 'knowlus' AND TABLE_NAME = %s", [unicode(self.sequence_name)])
        val = long(cursor.fetchone()[0])
        discard = cursor.fetchall()
        setattr(model_instance, self.attname, val)
        return val
    else:
        return long(old_val)