2013-04-26 5 views
6

La shell di Django si comporta (almeno per me) inaspettatamente quando si lavora con le impostazioni locali. La convalida del modulo di un campo decimale separato da virgole funziona quando si chiama da uno script esterno e non riesce a chiamare da django shell (ipython).python django shell (ipython) comportamento inatteso o bug?

iniziare un nuovo progetto ho ottenuto i seguenti file:

local_forms/ 
├── local_forms 
│   ├── __init__.py 
│   ├── models.py 
│   ├── settings.py 
│   ├── urls.py 
│   └── wsgi.py 
├── manage.py 
├── my_form.py 
├── test_form.py 

local_forms/models.py:

from django.db import models 

class MyModel(models.Model): 
    val=models.DecimalField("value",max_digits=11,decimal_places=2) 

my_form.py

from django import forms 
from django.conf import settings 
from local_forms.models import MyModel 


class MyForm(forms.ModelForm): 
    val = forms.DecimalField(localize=True) 

    def __init__(self,*args,**kwargs): 
     super(MyForm,self).__init__(*args,**kwargs) 
     self.fields['val'].localize=True 
     if __debug__: 
      print self.fields['val'].localize 
      print ("Separator: "+settings.DECIMAL_SEPARATOR) 
      print ("Language: " +settings.LANGUAGE_CODE) 

    class Meta: 
     model=MyModel 

test_form.py:

#!/usr/bin/env python 
import os 
import sys 

if __name__ == "__main__": 
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "local_forms.settings") 

    import my_form 

    form=my_form.MyForm({'val':'0,2'}) 

    print ("Is bound: %s" % form.is_bound) 
    print ("Form valid %s" % form.is_valid()) 
    print("Errors in val: %s" % form['val'].errors) 

Calling rendimenti ./test_form.py:

./test_form.py 

True 
Separator: . 
Language: de-de 
Is bound: True 
Form valid True 
Errors in val: 

fare la stessa cosa in guscio django: pitone manage.py guscio

In [1]: import my_form as mf 

In [2]: form=mf.MyForm({'val':'0,2'}) 
True 
Separator: . 
Language: de-de 

In [3]: form.is_valid() 
Out[3]: False 

In [4]: form['val'].errors 
Out[4]: [u'Enter a number.'] 

Riassumendo: Se inizio la shell Django (che sul mio pc usa ipython) le impostazioni internazionali in qualche modo non funzionano. Fare esattamente lo stesso in una sceneggiatura funziona perfettamente. Puoi spiegare questo comportamento?

+0

Testato con interprete bpython e ottenuto lo stesso errore. Forse alcune impostazioni non vengono importate o alcuni percorsi non vengono caricati. –

risposta

6

I comandi di gestione Django, incluso shell, reimpostano la lingua su 'en-us', quindi il problema. La spiegazione di questo comportamento è in the Django Documentation:

Per impostazione predefinita, il BaseCommand.execute() metodo imposta l'hardcoded 'it-it' locale perché alcuni comandi forniti con Django eseguire diverse operazioni (ad esempio, l'utente-facing content rendering e database) che richiedono un linguaggio stringa system-neutral (per il quale utilizziamo 'en-us').

Il vostro esempio funziona nel guscio se si attiva il linguaggio corretto:

>>> from django.utils.translation import get_language 
>>> get_language() 
    > 'en-us' 
>>> import my_form as mf 
>>> form=mf.MyForm({'val':'0,2'}) 
True 
Separator: . 
Language: de-de 
>>> form.is_valid() 
    > False 
>>> from django.utils.translation import activate 
>>> activate('de-de') 
>>> get_language() 
    > 'de-de' 
>>> form=mf.MyForm({'val':'0,2'}) 
True 
Separator: . 
Language: de-de 
>>> form.is_valid() 
    > True 

Su un lato nota, si dovrebbe sempre controllare la lingua corrente utilizzando get_locale() invece di basarsi su settings.

+0

Grazie mille, mi ci è voluto tutto il giorno per scoprire che era a causa della shell. Forse dovrebbe esserci qualche tipo di avvertimento, ma questa è un'altra domanda – ProfHase85