2015-04-02 4 views
6

difficoltà utilizzando il nuovo DurationField in Django 1.8Durationfield Django

Sto avendo un po 'di problemi con il Django di nuova DurationField per i modelli.

Desidero che l'utente sia in grado di scegliere se la durata di un evento sulla mia webapp è di 1 giorno, 3 giorni o 5 giorni, con la scelta predefinita di 3 giorni.

All'inizio del mio modello, dichiaro le scelte:

SHORT = datetime.timedelta(days=1) 
MEDIUM = datetime.timedelta(days=3) 
LONG = datetime.timedelta(days=5) 
DURATION_CHOICES = ((SHORT, '1 day'),(MEDIUM, '3 days'), (LONG, '5 days'),) 

Poi di seguito, dichiaro la DurationField:

duration = models.DurationField(choices = DURATION_CHOICES, default = MEDIUM) 

ho creato un ModelForm per il modello, e la resa su il modello appropriato. Nel modulo, "3 giorni" era la scelta preselezionata nel menu a discesa e "1 giorno" e "5 giorni" sono anche opzioni. Tuttavia, quando invio il modulo, visualizzo l'errore di convalida del modulo "Seleziona una scelta valida. 3 giorni, 0:00:00 non è una delle scelte disponibili."

Tuttavia, quando tolgo le scelte da DurationField e lascio il default:

duration = models.DurationField(default = MEDIUM) 

posso presentare senza problemi. Cosa sto facendo di sbagliato qui?

risposta

0

In qualche modo l'opzione choices non corrisponde alla stringa timedelta quando render o convertita in template.

E il ModelDurationFieldField DurationField Non funziona ...

ho risolto utilizzando ChoiceField

Codice:

class TestForm(ModelForm): 
    SHORT_1 = str(timedelta(days=1)).replace('day,', '') 
    SHORT = SHORT_1.replace(' ',' ') 
    MEDIUM_1 = str(timedelta(days=3)).replace('days,', '') 
    MEDIUM = MEDIUM_1.replace(' ',' ') 
    LONG_1 = str(timedelta(days=-5)).replace('days,', '') 
    LONG = LONG_1.replace(' ',' ') 

    DURATION_CHOICES = ((SHORT, '1 day'),(MEDIUM, '3 days'), (LONG, '5 days'),) 
    duration = forms.ChoiceField(widget = forms.Select(), 
        choices = (DURATION_CHOICES), initial='MEDIUM', required = True,) 

    class Meta: 
     model = Test 
     fields = ['duration'] 

non so non è raccomandato o no. .. Sto cercando troppo perché Django non funziona in modo predefinito ...

1

lo hanno fatto hanno lo stesso problema il problema è spiegato in questo biglietto bugfix

https://code.djangoproject.com/ticket/24897

modo migliore per risolvere questo problema è quello di utilizzare questo campo personalizzato in attesa della squadra Django per risolvere questo:

""" 
    This is a temp DurationField with a bugfix 
    """ 
    standard_duration_re = re.compile(
     r'^' 
     r'(?:(?P<days>-?\d+) (days,)?)?' 
     r'((?:(?P<hours>\d+):)(?=\d+:\d+))?' 
     r'(?:(?P<minutes>\d+):)?' 
     r'(?P<seconds>\d+)' 
     r'(?:\.(?P<microseconds>\d{1,6})\d{0,6})?' 
     r'$' 
    ) 

    # Support the sections of ISO 8601 date representation that are accepted by 
    # timedelta 
    iso8601_duration_re = re.compile(
     r'^P' 
     r'(?:(?P<days>\d+(.\d+)?)D)?' 
     r'(?:T' 
     r'(?:(?P<hours>\d+(.\d+)?)H)?' 
     r'(?:(?P<minutes>\d+(.\d+)?)M)?' 
     r'(?:(?P<seconds>\d+(.\d+)?)S)?' 
     r')?' 
     r'$' 
    ) 
    def parse_duration(value): 
     """Parses a duration string and returns a datetime.timedelta. 

     The preferred format for durations in Django is '%d %H:%M:%S.%f'. 

     Also supports ISO 8601 representation. 
     """ 
     match = standard_duration_re.match(value) 
     if not match: 
      match = iso8601_duration_re.match(value) 
     if match: 
      kw = match.groupdict() 
      if kw.get('microseconds'): 
       kw['microseconds'] = kw['microseconds'].ljust(6, '0') 
      kw = {k: float(v) for k, v in six.iteritems(kw) if v is not None} 
      return datetime.timedelta(**kw) 

    class DurationField(CoreDurationField): 
     def to_python(self, value): 
      if value is None: 
       return value 
      if isinstance(value, datetime.timedelta): 
       return value 
      try: 
       parsed = parse_duration(value) 
      except ValueError: 
       pass 
      else: 
       if parsed is not None: 
        return parsed 
      raise exceptions.ValidationError(
       self.error_messages['invalid'], 
       code='invalid', 
       params={'value': value}, 
      ) 
+0

sguardi come quel biglietto è stato risolto in 1.8.3 https://docs.djangoproject.com/en/1.8/releases/1.8.3/ – nnyby