Pergunta

Estou apenas me familiarizando com Flask, WTForms (e flask-WTF).Sinto que estou perdendo alguma coisa.

De acordo com Documentos WTForms "o HTML do seu campo de formulário pode ser gerado para você, mas permitimos que você o personalize em seus modelos.Isso permite que você mantenha a separação entre código e apresentação e mantenha esses parâmetros confusos fora do seu código python."

O método sugerido para modelar entradas de rádio HTML é:

class ExmapleForm(Form):
    language = RadioField(u'Programming Language', choices=[('py', 'Python'), ('js', 'JavaScript')])

....e a ​​maneira sugerida de modelar entradas de rádio HTML é:

{% for subfield in form.radio %}
    <tr>
        <td>{{ subfield }}</td>
        <td>{{ subfield.label }}</td>
    </tr>
{% endfor %}

Com essa abordagem, a propriedade de escolhas "que é uma sequência de pares (valor, rótulo)" não está misturando a apresentação com os modelos?

Existe uma maneira de mover o rótulo para o modelo e combiná-lo com o valor?

Foi útil?

Solução

Pergunta interessante.Se pensarmos em termos do padrão MVC, acho que a lista de opções que aparece em um menu suspenso pertence ao Modelo, não à Visualização.Então eu não teria essas escolhas definidas pelo designer no template.Acredito que concordamos nisso, certo?

Ter a lista de opções codificadas no formulário como no seu exemplo é melhor, mas também não é o ideal.Provavelmente você tem um Language modelo ou entidade semelhante, correto?Esse modelo é a autoridade em escolhas válidas de linguagem de programação, portanto deve ser aquele que fornece a lista de escolhas válidas para qualquer pessoa, seja um formulário ou outro subsistema.

Como você mencionou na sua pergunta, cada opção possui um nome interno e um nome de exibição.E já que estamos falando de strings de exibição, não vamos esquecer que o u'Programming Language' o título do seu campo se enquadra na mesma categoria de strings de exibição.Essas strings deveriam ser de responsabilidade do designer do modelo?Não sei, isso é uma zona cinzenta entre modelo e apresentação, acho que o designer deveria ter autoridade na aparência das coisas, mas não no conteúdo.

Se você quiser ter mais controle sobre a aparência dessas strings de exibição, poderá usar um kit de ferramentas de tradução como o gettext (por meio do Flask-Babel, por exemplo).Se seu aplicativo renderizar texto por meio de gettext, você poderá mapear quaisquer strings do código ou do modelo para outras strings.Isso é usado para traduzir para outros idiomas, mas você também pode usá-lo para ter controle separado sobre como as strings são exibidas no idioma nativo do aplicativo.O mapeamento é feito em um arquivo de dados externo, então acho que isso alcança a independência que você procura.

Outras dicas

do ponto de vista puramente teórico que não parece ser uma boa ideia.Se você tivesse que conectar o rótulo com o valor real no modelo, isso significaria ter uma lógica de negócios no modelo.

Além disso, como você imagina o código exato fazendo isso?Isso exigiria o subcampo-contexto dentro da instrução atribuindo o rótulo.Eu não posso imaginar esse código é bom no modelo.E seria parte da lógica de apresentação como deveria?

Aqui está a solução que encontrei (para manter a separação).Pode ser um exagero, mas vou experimentar e ver como ele se adapta.

Em formulários.py:

import sys
sys.path.append("templates")
import constants

class ExmapleForm(Form):
    language = RadioField('language', choices=constants.languages['choices'], validators=constants.languages['validators'])

Então criei um arquivo na pasta de templates chamado constantes.py:

from wtforms.validators import InputRequired

languages = {
    'choices': [
        ('py', 'Python'),
        ('js', 'JavaScript')
    ],
    'validators': [
        InputRequired(message = 'Please Select')
    ]
}

Espero que ajude (e dê certo)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top