Пользовательское поле Django выдает ошибку при редактировании в админке
Я пытаюсь реализовать пользовательское поле Django, которое будет хранить в БД имя одного из моих классов модели (например, "Cat", "Dog", "Restaurant", "SuperPrivateCommercialDataPiece" и т. Д.) И возвращать объект класса, когда просил:
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
, задавать __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)
И в приведенном выше коде это работает так же, как и ожидалось. Я также зарегистрировал некоторые из моих моделей, содержащих такие поля, в admin, и теперь я даже могу создавать такие объекты; ввод текста создается для полей MyGloriousFieldType.
Кризис начинается, когда я пытаюсь редактировать уже существующий объект с полем MyGloriousFieldType. Во-первых, он заполняет текстовое поле словом "объект Cat", а не просто "Cat". Во-вторых, когда я изменяю его обратно на "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)
Итак, что я делаю не так?
1 ответ
Ну, я понял это. Проблема внутри самого ядра Django. Поля просто не могут возвращать объекты Python, содержащие некоторые models.Field
атрибуты, такие как prepare_database_save
в противном случае происходит ошибка. Мой взлом, чтобы решить, что должен был вернуть кортеж (MyClassObject, )
вместо просто MyClassObject
в to_python()
, Странно, но что я могу сделать... Может быть, я постараюсь опубликовать проблему где-нибудь на странице GitHub Джанго.