Итак, я создал пользовательский ModelField, расширяющий CharField, чтобы он лучше проверял пустую строку и позволял мне запускать проверку и очистку пользовательской бизнес-логики.Код ниже:
class CustomTextField(models.CharField):
10 def __init__(self, *args, rule="TextRule", **kwargs):
11 self.rule = rule
12 super().__init__(args, kwargs)
13
14 def deconstruct(self):
15 name, path, args, kwargs = super().deconstruct()
16 # Only include kwarg if it's not the default
17 if self.rule != "TextRule":
18 kwargs['rule'] = self.rule
19 return name, path, args, kwargs
20
21 def validate(self, value, model_instance):
22 super().validate(value, model_instance)
23 # skip special cases here
24 if self.blank and self.rule == TextRule:
25 return
26 rule_module = __import__("webapp.rules", fromlist=['blah'])
27 class_ = getattr(rule_module, self.rule)
28 rule = class_(value)
29 result = rule.validate()
30 if result != "":
31 raise ValidationError(result)
32
33 def clean(self, value, model_instance):
34 value = super().clean(value, model_instance)
35 rule_module = __import__("webapp.rules", fromlist=['blah'])
36 class_ = getattr(rule_module, self.rule)
37 rule = class_(value)
38 return rule.clean()
Итак, идея в том, что это, по сути, CharField, который запускает мой объект TextRule по умолчанию, но может быть переопределен для запуска других правил типа текста (например, номер телефона, электронная почта и т. Д.), чтобы выполнить пользовательскую проверку и очистку данных.
Но всякий раз, когда я назначаю это поле атрибуту модели, переопределяя правило:
zip_code = CustomTextField(rule="ZipCodeRule", max_length=5)
, сервер django постоянно выдает мне следующее сообщение:
File "/home/blah/python37env/lib/python3.7/site-packages/django/db/models/base.py", line 156, in __new__
new_class.add_to_class(obj_name, obj)
File "/home/blah/python37env/lib/python3.7/site-packages/django/db/models/base.py", line 321, in add_to_class
value.contribute_to_class(cls, name)
File "/home/blah/python37env/lib/python3.7/site-packages/django/db/models/fields/__init__.py", line 743, in contribute_to_class
if not getattr(cls, self.attname, None):
TypeError: getattr(): attribute name must be string
То же самое происходит, когда я пытаюсь запустить makemigrations.Полностью озадачен тем, что исходный код django, указанный в ошибке, не так легко понять.