Для доступа к значению поля пользовательской модели Django (не первичного BigAutoField) после сохранения - PullRequest
0 голосов
/ 03 ноября 2011

У меня есть настраиваемое поле 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 - это BigAutoField в XYZ. Хотя в базе данных mysql автоинкрементное значение для этого же видно.

1 Ответ

0 голосов
/ 24 ноября 2011

У меня было специальное требование иметь uuid в качестве первичного ключа и 1 поле в качестве автозаполя в таблице.Так как 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)
...