Обычное явление, которое у меня возникает с одним конкретным проектом, заключается в том, что он требует от пользователя ввода размеров (для ширины / глубины / высоты) в футах и дюймах. Для этого измерения необходимо выполнить вычисления, поэтому я работал над пользовательским типом поля, который принимает измерение в футах / дюймах (например, 1'-10 ") и сохраняет его в базе данных как десятичное число, используя регулярное выражение для анализа ввода. Поле всегда отображается для конечного пользователя в футах-дюймах (с возможной целью написания
метод для возможности отображения в метрике и взаимодействия с measure.py и geodjango). То, что я имею до сих пор, определенно не СУХО, но кроме этого, у меня проблемы с проверкой на уровне формы. Само поле пользовательской модели работает правильно (из того, что я видел), и я написал метод очистки поля формы, который должен работать для проверки поля. Мой вопрос заключается в том, как подключить это поле формы обратно к форме моей модели для работы со всеми полями ширины / глубины / высоты.
Я думаю, что, возможно, переопределить init для формы модели (a la self.fields ['deep'] ...), но я не совсем уверен, куда идти дальше ...
DCML_PATTERN = re.compile(r'^(?P<feet>\d+)(?P<dec_inch>\.?\d*)\'?$')
FTIN_PATTERN = re.compile(r'^(?P<feet>\d+)\'?\s*-?\s*(?P<inch>[0-9]|10|11)?\"?$')
class FtInField(models.Field):
__metaclass__ = models.SubfieldBase
empty_strings_allowed = False
def db_type(self):
return 'double'
def get_internal_type(self):
return "FtInField"
def to_python(self,value):
if value is u'' or value is None:
return None
if isinstance(value, float):
m = FTDCML_PATTERN.match(str(value))
if m is None:
raise Exception('Must be an integer or decimal number')
feet = int(m.group('feet'))
dec_inch = float(m.group('dec_inch') or 0)
inch = dec_inch * 12
return "%d\'-%.0f\"" % (feet,inch)
return value
def get_db_prep_value(self,value):
if value is u'' or value is None:
return None
m = FTIN_PATTERN.match(value)
if m is None:
raise Exception('Must be in X\'-Y" Format')
feet = int(m.group('feet'))
inch = int(m.group('inch') or 0)
return (feet + (inch/float(12)))
class FtInField(forms.Field):
def clean(self,value):
super(FtInField, self).clean(value)
if value is u'' or value is None:
raise forms.ValidationError('Enter a dimension in X\'-Y" format')
m = FTIN_PATTERN.match(value)
if m is None:
raise forms.ValidationError('Must be in X\'-Y" Format')
feet = int(m.group('feet'))
inch = int(m.group('inch') or 0)
value = '%d\'-%.0f"' % (feet,inch)
return value
class ProductClass(models.Model):
productname = models.CharField('Product Name', max_length=60,blank=True)
depth = FtInField('Depth (Feet/Inches)')
width = FtInField('Width (Feet/Inches)')
height = FtInField('Height (Feet/Inches)')
class ProductClassForm(forms.ModelForm):
depth = FtInField()
width = FtInField()
height = FtInField()
class Meta:
model = ProductClass
class ProductClassAdmin(admin.ModelAdmin):
form = ProductClassForm