2017-08-15 3 views
0

Je suis en train de soulever une erreur de validation où:django - Formulaire ValidationError ne fonctionne pas

1) si la date sélectionnée dans le champ start_date est la veille aujourd'hui il soulèvera et erreur. quand je le soumets jeter cette erreur

'<' pas pris en charge entre les instances de 'NoneType' et 'datetime.date'

2) si la date de fin est une date antérieure à la date de début, il va générer une autre erreur. Pour cette partie son travail partiel où je ne sauve pas le formulaire soumis mais il ne soulève pas et erreur de validation

Je sais que ce n'est pas la première fois que quelqu'un pose cette question mais j'ai suivi la réponse donnée par d'autres et c'est ne fonctionne pas, où je me trompe?

Toute aide est très appréciable.

Ci-dessous mon code:

model.py:

class Leave(models.Model): 
    employee = models.ForeignKey(Employee, on_delete=models.CASCADE, related_name='+') 
    start_date = models.DateField() 
    end_date = models.DateField() 
    duration = models.FloatField() 

form.py:

class LeavesDetailForm(forms.ModelForm): 

    class Meta: 
     model = Leave 
     fields = ('employee', 'type', 'status', 'start_date', 'end_date', 'duration', 'comment') 
     widgets = {'start_date': forms.DateInput(attrs={'type': 'date'}), 
        'end_date': forms.DateInput(attrs={'type': 'date'}), 
        'employee': forms.HiddenInput(), 
        'duration': forms.HiddenInput(), 
        'status': forms.HiddenInput()} 

    def clean(self): 
     start_date = self.cleaned_data.get("start_date") 
     end_date = self.cleaned_data.get("end_date") 
     if end_date < start_date: 
     msg = u"End date should be greater than start date." 
     self._errors["end_date"] = self.error_class([msg]) 
     raise forms.ValidationError("End date should be greater than start date.!") 

    def clean_start_date(self): 
     start_date = self.cleaned_data.get('start_date') 
     if self.instance.start_date < datetime.date.today(): 
      raise forms.ValidationError("The date cannot be in the past!") 
     return start_date 

view.py:

def my_leaves_view(request): 
    form = LeavesDetailForm(request.POST or None) 
    leaves_log = Leave.objects.all().filter(employee=request.user.profile.employee.id) 
     if form.is_valid(): 
     inst = form.save(commit=False) 
     inst.start_date = form.cleaned_data['start_date'] 
     inst.end_date = form.cleaned_data['end_date'] 
     duration = (inst.end_date - inst.start_date).days 
     inst.duration = duration 
     inst.save() 
     return HttpResponseRedirect('my_leaves_content.html') 
    context = {'form': form} 
    return render(request, 'hrm/my_leaves/my_leaves_content.html', context) 

Répondre

0

On dirait que vous venez nommé la fonction erronée. Remplacez clean_date par clean_start_date comme il se doit dans le format clean_function_name.

J'espère que ça aide!

+0

Salut @Jahongir I switch 'def clean_date (self):' à 'def clean_start_date (self):' mais malheureusement, il ne fonctionne toujours pas. –

0

Dans la méthode clean, start_date ou end_date peut être None si l'utilisateur n'a pas présenté une date valide.

Comme l'erreur le suggère, Python ne vous laissera pas comparer une instance date avec None.

Vous devez vérifier que vous avez des dates valides de cleaned_data avant de les comparer:

if end_date is not None and start_date is not None and end_date < start_date: 

Dans la méthode clean_start_date, vous devez utiliser start_date que vous les cheveux de cleaned_data, non self.instance.start_date:

def clean_start_date(self): 
    start_date = self.cleaned_data.get('start_date') 
    if start_date < datetime.date.today(): 
     raise forms.ValidationError("The date cannot be in the past!") 
    return start_date 
+0

Salut merci pour vous répondre @Alasdair, j'ai changé ma condition à 'si start_date

+0

Les champs sont nettoyés individuellement avant l'exécution de la méthode 'clean'. Si un champ est invalide, il ne sera pas dans 'nettoyé_data' quand la méthode' clean' sera exécutée, donc vous devez vérifier si 'get()' a retourné 'None'. – Alasdair