0

モデル クラスの 1 つの名前 (「Cat」、「Dog」、「Restaurant」、「SuperPrivateCommercialDataPiece」など) を DB に保持し、クラス オブジェクトを返すカスタム Django フィールドを実装しようとしています。リクエスト:

class Cat(models.Model):
    ...

class SomeDataPiece(models.Model):
    relatedTo = MyGloriousFieldType(null=True)

...

newPiece = SomeDataPiece()
newPiece.relatedTo = Cat
print newPiece.relatedTo # should print <class 'myproj.myapp.models.Cat'>

そして、私は本当にこれを作りました。models.Field、 set__metaclass__などをサブクラス化しました。

class MyGloriousFieldType(models.Field):

    description = "No description, just gloriosity."

    __metaclass__ = models.SubfieldBase

    def __init__(self, *args, **kwargs):
        kwargs['max_length'] = 40
        super(BlockTypeField, self).__init__(*args, **kwargs)

    def db_type(self, connection):
        return 'char(40)'

    def to_python(self, value):
        if not value:
            return None
        elif inspect.isclass(value) and issubclass(value, models.Model):
            return value
        elif hasattr(myproj.myapp.models, value):
            return getattr(myproj.myapp.models, value)
        else:
            raise ValidationError("Invalid model name string")

    def get_db_prep_value(self, value, **kwargs):
        if inspect.isclass(value) and issubclass(value, models.Model):
            return value.__name__
        else:
            # it is actually never raised
            raise ValidationError("Invalid value, Model subclass expected")

    def value_to_string(self, instance):
        value = self._get_val_from_obj(obj)
        return self.get_prep_value(value)

上記のコードでは、期待どおりに動作します。また、そのようなフィールドを含むモデルのいくつかを管理者に登録しました。今では、そのようなオブジェクトを作成することもできます。MyGloriousFieldType フィールドのテキスト入力が作成されます。

MyGloriousFieldType フィールドを持つ既存のオブジェクトを編集しようとすると、危機が始まります。まず、テキスト フィールドに "Cat" ではなく "Cat object" を入力します。次に、「Cat」に戻して「変更を保存」をクリックすると、エラーが発生します。

TypeError at /admin/myapp/somedatapiece/3/
  unbound method prepare_database_save() must be
  called with Cat instance as first argument (got 
  MyGloriousFieldType instance instead)

それで、私は何を間違っていますか?

4

1 に答える 1