2010-07-08 15 views
17

Sto scrivendo un'app Django da utilizzare in un paese in cui usano la virgola come decimal separator. Ho un modello che contiene un django.db.models.DecimalField e io uso model forms. Come posso rendere il rendering del campo risultante con virgola e accettare la virgola indietro dall'utente?Crea moduli Django usa la virgola come separatore decimale

Dopo la advice di jweyrich, ho aggiornato la mia domanda da Django 1.1 a Django 1.2 e modificato il mio settings.py contenere i seguenti:

LANGUAGE_CODE = 'nb' 
LANGUAGES = (
    ('nb', 'Norwegian'), 
) 
USE_I18N = True 
USE_L10N = True 
DECIMAL_SEPARATOR = ',' 
THOUSAND_SEPARATOR = ' ' 
MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware', 
    'django.middleware.locale.LocaleMiddleware', 
    'django.middleware.common.CommonMiddleware', 
    'django.contrib.auth.middleware.AuthenticationMiddleware', 
    'django.middleware.csrf.CsrfViewMiddleware', 
) 

Per quanto posso vedere, questo è tutto ciò che the documentation chiamate per. Ora funziona per i moduli se imposto localization=True nel campo modulo. Funziona né in model forms né in the admin site, tuttavia.

Ho scoperto uno Django ticket e uno Django changeset risultante da prima della versione 1.2. Se li capisco correttamente, era il caso che i widget usavano automaticamente la localizzazione del formato, ma dopo che questa localizzazione della patch deve essere attivata esplicitamente dando il parametro della parola chiave localization=True al campo del modulo. C'è un modo per rendere i moduli di amministrazione impostati localization=True sui loro campi?

risposta

21

Sì, la localizzazione deve essere attivata esplicitamente per ogni campo. Per un modulo tipo (compresi quelli utilizzati in app admin), un modo conveniente per farlo è quello di creare una sottoclasse ModelForm e accendere di localizzazione per ogni DecimalField:

import django 

class LocalizedModelForm(django.forms.ModelForm): 
    def __new__(cls, *args, **kwargs): 
     new_class = super(LocalizedModelForm, cls).__new__(cls, *args, **kwargs) 
     for field in new_class.base_fields.values(): 
      if isinstance(field, django.forms.DecimalField): 
       field.localize = True 
       field.widget.is_localized = True 
     return new_class 

Quindi è possibile definire la classe ModelForm personalizzato e l'uso in app admin:

class FooForm(LocalizedModelForm): 

    class Meta: 
     model = Foo 


django.admin.site.register(Foo, form=FooForm) 
+0

Soluzione brillante ed elegante. – scum

+4

Preferirei renderlo un mixin: 'LocalizationMixin (object): ...' e 'FooForm (LocalizationMixin, forms.ModelForm)', così puoi continuare ad usare per es. 'FooForm (LocalizationMixin, floppyforms.ModelForm)' – Webthusiast

+0

Cosa fare se si desidera abilitare la localizzazione direttamente per Modelli? Non ModelForms. Caso di utilizzo: visualizza la risposta a una richiesta HTTP AJAX che registra i dati e desidera archiviare tali dati (contenenti numeri con la virgola come separatore di migliaia) in un modello con un campo Decimale. Non riesci a trovare una soluzione per questo. – jorgeas80

8

Esatto, sembra una rottura fastidiosa che mi sorprende che nessuno abbia segnalato. A causa della modifica che menzioni, la localizzazione deve essere esplicitamente attivata per ogni campo nell'app di amministrazione o nel modulo del modello. Il modo migliore per farlo sarebbe definire un ModelForm personalizzato da utilizzare sia nell'amministratore sia nella tua app e impostare il dizionario widgets per abilitare la localizzazione su ciascun campo pertinente.

class MyModelForm(forms.ModelForm): 
    class Meta: 
     model = MyModel 
     widgets = { 
      'my_decimal_field': forms.TextInput(attrs={'localization': True}), 
     } 
+3

Questo imposta solo un attributo nell'HTML, ma tu mi metti sulla giusta traccia (un ModelForm personalizzato è risultato essere la strada da percorrere), così ottieni il bounty. Grazie! Pubblicherò la soluzione di lavoro come risposta separata. –

7

in Django> = 1.6 c'è una semplice soluzione a questo:

from django.forms import ModelForm 

class YourModelForm(ModelForm): 
    class Meta: 
     model = YourModel 
     localized_fields = '__all__' 

django.admin.site.register(YourModel, form=YourModelForm) 

See the official documentation for a more verbose explanation.

+1

E per forms.Form, 'forms.DecimalField (label = 'Foo', localize = True)' funziona. – chhantyal

+0

parentesi ridondanti che circonda '__all__' – Chris

+0

cambiato, grazie a @Chris – zvyn

Problemi correlati