1

それ自体とのnull可能な外部キー関係を持つモデルがあります(この「自己」は、この外部キーを持つ任意のモデルにすることができます)。この外部キーは、循環関係を防ぐカスタム クラスです。

への呼び出しsuper()__init__含まnull=Trueblank=Trueているため、South の検査規則に含める必要があります。これにより、少なくともスキーマ移行は機能しますが、移行は依然として失敗します。

次のコードは、カスタム外部キー、インスペクション ルール、および外部キーを使用するモデルを示しています。

# Foreign key
class ParentField(models.ForeignKey)
    def __init__(self, verbose_name=None, **kwargs):
        super(ParentField, self).__init__('self', verbose_name=verbose_name, null=True, blank=True, **kwargs)

    @staticmethod
    def checkcyclic(object, attr):
        '''Check for a cyclic relationship'''
        pass

# Introspection rules
add_introspection_rules([
    (
        [ParentField],
        [],
        {
            'null': ['null', {'default': True}],
            'blank': ['blank', {'default': True}],
        }
    )
], ["^test\.models\.fields\.ParentField"])

# Model
class Relation(Model):
    parent = ParentField(related_name='child_set')

移行すると、次のエラーが発生します。

$ ./manage.py migrate
[..]
super(ParentField, self).__init__('self', verbose_name=verbose_name, null=True, blank=True, **kwargs)
TypeError: __init__() got multiple values for keyword argument 'to'

以下のようなルールを追加してみましたが、何も変わりませんでした。

'to': ['rel.to', {'default': 'test.models.Relation'}],

私が間違ったやり方をしていることや、これに対する解決策のヒントを教えてもらえますか?

4

2 に答える 2

2

最終的に、このソリューションは私にとってはうまくいきました.googlegroupsのShaiの功績によるものです:

South は、カスタム フィールドのインスタンスを作成しようとすると、クラスのさまざまな kwargs の値を (ルールを使用して) 収集します。これらの 1 つが "to"引数です。移行コードで指定されていることがわかります。

次に、収集した値を取得してコンストラクターに渡します。つまり、事実上、あなたは電話を受けます

fields.ParentField(related_name='set', to=orm['module.ModelClass'])

ただし、あなたの内部では、__init__これは次のように変換されます

models.ForeignKey('self', related_name='set', to=orm['module.ModelClass'])

したがって、'to'引数には 2 つの値があります。1 つ目は、位置指定 'self'です。

少なくとも 1 つの解決策は、null および空の引数に対して推奨したのと同じことを行うことです。呼び出しに直接ではなく、kwargs に追加します。

kwargs.setdefault('to', 'self') 
于 2012-10-16T13:35:36.097 に答える