2017-02-25 55 views
2

我如何防止在同一時間內租用汽車的重複問題 汽車已被租用或保留爲前:01/01/2017至01/03/2017 如果我trie租這輛汽車這之間的時間段日期「2017年1月1日至2017年1月3日」應該給我像驗證錯誤錯誤在現場Django CreateView顯示錯誤無法正常工作

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) 

f orms.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 

回答

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