Поле формы SQL Alchemy WTForms по умолчанию, но не вставляйте пустые данные

#sqlalchemy #wtforms #form-fields

Вопрос:

Итак, у меня есть эти формы wt:

 ProfessionalAddress = FormField(AdressForm, default=lambda: ProfessionalAddress())  

которая связывает подформу с моей основной формой. Чтобы убедиться, что подформа отображается, я добавил default поведение, которое создает пустоту ProfessionalAddress , если связь не существует.

Но проблема в том, что в некоторых случаях мне не нужна эта подформа, и она не отображается, поэтому поля не отправляются.

Но когда я звоню form = MainForm(formdata=request.form) , так как поля не отправляются, form.ProfessionalAddress устанавливается ProfessionalAddress() значение, которое генерирует ошибку, так как моя база данных не допускает там пустых записей.

Я мог бы справиться с этим на уровне контроллера (что-то вроде if form.ProfessionalAddress is empty: form.ProfessionalAddress = None ), но это кажется банальным, и я бы предпочел разобраться с этим в Form описании.

  • Как я могу справиться с этим делом?
  • Могу ли я отличить случай создания формы от случая заполнения формы?
  • Или я могу заполнить значение по умолчанию позже (например. во время создания представления)?
  • Или мой подход совершенно неверен?

Надеюсь, все ясно!

Спасибо

Ответ №1:

Один из способов сделать это-переопределить data свойство поля формы, заставив его возвращать None значения всех полей None поля формы (или любой другой тест, который вы хотите применить).

 class MyFormField(wtforms.FormField):   @property  def data(self):  data = {name: f.data for name, f in self._fields.items()}  if any(filter(lambda v: v is not None, data.values())):  return data  return None   class MyForm(wtforms.Form):  name = wtforms.StringField()  professional_address = MyFormField(AddressForm, default=ProfessionalAddress())  

если мы попробуем это сделать

 form = MyForm(data={'name': 'Alice'}) for f in form:print(f) form = MyForm(formdata=MultiDict({'name': 'Alice'})) form.validate() print(form.data)  form = MyForm(data={'name': 'Bob', 'professional_address': ProfessionalAddress(line1='1 High Street', line2='Dullsville')}) for f in form:print(f) form = MyForm(formdata=MultiDict([('name', 'Bob'), ('professional_address-line1', '1 High Street')])) form.validate() print(form.data)  

мы видим, что форма отображается должным образом и None возвращается, если поля профессионального адреса не заполнены.

 lt;input id="name" name="name" type="text" value="Alice"gt; lt;table id="professional_address"gt;lt;trgt;lt;thgt;lt;label for="professional_address-line1"gt;Line1lt;/labelgt;lt;/thgt;lt;tdgt;lt;input id="professional_address-line1" name="professional_address-line1" required type="text" value=""gt;lt;/tdgt;lt;/trgt;lt;trgt;lt;thgt;lt;label for="professional_address-line2"gt;Line2lt;/labelgt;lt;/thgt;lt;tdgt;lt;input id="professional_address-line2" name="professional_address-line2" required type="text" value=""gt;lt;/tdgt;lt;/trgt;lt;/tablegt;  
 {'name': 'Alice', 'professional_address': None}  
 lt;input id="name" name="name" type="text" value="Bob"gt; lt;table id="professional_address"gt;lt;trgt;lt;thgt;lt;label for="professional_address-line1"gt;Line1lt;/labelgt;lt;/thgt;lt;tdgt;lt;input id="professional_address-line1" name="professional_address-line1" required type="text" value="1 High Street"gt;lt;/tdgt;lt;/trgt;lt;trgt;lt;thgt;lt;label for="professional_address-line2"gt;Line2lt;/labelgt;lt;/thgt;lt;tdgt;lt;input id="professional_address-line2" name="professional_address-line2" required type="text" value="Dullsville"gt;lt;/tdgt;lt;/trgt;lt;/tablegt;  
 {'name': 'Bob', 'professional_address': {'line1': '1 High Street', 'line2': None}}