-1

モデルの1つに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()

しかし、現在、cがXYZのBigAutoFieldであるxcにアクセスできません。mysqlデータベースでは、同じものの自動インクリメントされた値が表示されますが。

4

1 に答える 1

0

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)
于 2011-11-24T05:05:09.490 に答える