Django CreateView显示错误无法正常工作

时间:2017-02-25 00:52:52

标签: python django django-class-based-views

如何防止同期租车的重复 这辆车已经租用或预留给:2017年1月1日至2017年3月1日 如果我想在这个日期之间租用这辆车“01/01/2017至01/03/2017”它应该给我一个错误,就像在现场右侧的验证错误

screen shot for my rental car app

models.py

class Car(models.Model):

    imatriculation = models.CharField(max_length=100, primary_key=True)
    marque = models.CharField(max_length=100)
    couleur = models.CharField(max_length=100)

class Contra(models.Model):

    car = models.ForeignKey(Car, on_delete=models.CASCADE)
    date_debut = models.DateField(null=True ,blank=True)
    heure_debut = models.TimeField(null=True ,blank=True)
    date_retour = models.DateField(null=True ,blank=True)
    heure_retour = models.TimeField(null=True ,blank=True)

forms.py

class CarForm(forms.ModelForm):

    class Meta:
        model = Car
        fields = ('imatriculation', 'marque',  'couleur')       


class ContraForm(forms.ModelForm):

    date_debut = forms.DateField(widget = AdminDateWidget())
    heure_debut = forms.TimeField(widget = AdminTimeWidget())
    date_retour = forms.DateField(widget = AdminDateWidget())
    heure_retour = forms.TimeField(widget = AdminTimeWidget())

    class Meta:
        model = Contra
        fields = ('car','date_debut','heure_debut',  
                 'date_retour','heure_retour')

views.py

class ContraCreate(CreateView):
    template_name = 'rentcar/contra_update.html'
    form_class = ContraForm
    model = Contra

    def form_valid(self, form):
                now_date = date.today()
                now_time = datetime.now().strftime('%H:%M:%S')
                x = Contra.objects.filter(location=self.request.user,
                    date_debut__lte=now_date, date_retour__gte=now_date)
                c = form.instance.car
                for e in x:
                    if c.imatriculation ==  e.car.imatriculation :
                    print ("Leased car")
                    ValidationError(_('Invalid value'))
                    return super(ContraCreate, self).form_invalid(form)
                return super(ContraCreate, self).form_valid(form) 

我找到了一个使用干净的解决方案

def clean(self):
    super(ContratForm, self).clean()
    form_car          = self.cleaned_data.get('car')    
    form_date_debut   = self.cleaned_data.get('date_debut')
    form_date_retour  = self.cleaned_data.get('date_retour')
    form_heure_debut  = self.cleaned_data.get('heure_debut')
    form_heure_retour = self.cleaned_data.get('heure_retour')
    h                 = form_car.imatriculation

    x1  = Contrat.objects.filter(location=self.user,car=h ,date_debut__lte=form_date_debut,date_retour__gte=form_date_retour)
    x2  = Contrat.objects.filter(location=self.user,car=h ,date_debut__gt=form_date_debut,date_debut__lt=form_date_retour,date_retour__gte=form_date_retour)
    x25 = Contrat.objects.filter(location=self.user,car=h ,date_debut__gt=form_date_debut,date_debut=form_date_retour,heure_debut__lt=form_heure_retour)
    x3  = Contrat.objects.filter(location=self.user,car=h ,date_debut__lte=form_date_debut,date_retour__gt=form_date_debut,date_retour__lt=form_date_retour)
    x35 = Contrat.objects.filter(location=self.user,car=h ,date_debut__lte=form_date_debut,date_retour=form_date_debut,heure_retour__gt=form_heure_debut)
    x4  = Contrat.objects.filter(location=self.user,car=h ,date_debut__gt=form_date_debut,date_retour__lt=form_date_retour)


    if x1:
        for k in x1:
            self._errors['car']          = "Deja reserve .contrat %s" %(k.id)
            self._errors['date_debut']   = k.date_debut.strftime('%d/%m/%Y')
            self._errors['date_retour']  = k.date_retour.strftime('%d/%m/%Y')
    elif x2:
        for k in x2:
            self._errors['car']          = "Deja reserve .contrat %s" %(k.id)
            self._errors['date_retour']  = ("<= %s" %(k.date_debut).strftime('%d/%m/%Y'))
    elif x25:
        for k in x25:
            self._errors['car']          = "Changer l'heur retour"
            self._errors['date_retour']  = ("= Date depart contrat %s" %(k.id))
            self._errors['heure_retour'] = ("< %s" %(k.heure_debut))
    elif x3:
        for k in x35:
            self._errors['car']          = "Deja reserve .contrat %s" %(k.id)
            self._errors['date_debut']   = (">= %s" %(k.date_retour).strftime('%d/%m/%Y'))
    elif x35:
        for k in x35:
            self._errors['car']          = "Changer l'heur de depart"
            self._errors['date_debut']   = ("= Date debut contrat %s" %(k.id))
            self._errors['heure_debut']  = ("> %s" %(k.heure_retour))
    elif x4:
        for k in x4:
            self._errors['car']          = "Deja reserve .contrat %s" %(k.id)
            self._errors['date_debut']   = k.date_debut.strftime('%d/%m/%Y')
            self._errors['date_retour']  = k.date_retour.strftime('%d/%m/%Y')

    return self.cleaned_data

1 个答案:

答案 0 :(得分:0)

当调用视图中的form_valid时,Django已经确定表单有效。查看the docs关于验证如何运作的说法。

您希望对数据库中的数据进行额外验证,可以通过表单中的overriding the clean stage of validation完成。

基于上述代码的解决方案如下所示:

def clean(self):
    '''This goes in ContraForm.py'''
    cleaned_data = super(ContraForm, self).clean()
    now_date = date.today()
    now_time = datetime.now().strftime('%H:%M:%S')
    x = Contra.objects.filter(location=self.request.user,
                date_debut__lte=now_date, date_retour__gte=now_date)
    c = form.instance.car
    for e in x:
        if c.imatriculation ==  e.car.imatriculation :
            raise ValidationError('Invalid debut date. Car already reserved.')
    return cleaned_data