2012-09-05 13 views
14

Modelin clean() yöntemi ve temel alan doğrulaması ile ilgili bir sorunum var. İşte benim modelim ve clean() yöntemi. bazı değerlerin doğru aralıktamodel ve alan geçerliliğinde clean() yöntemi

class Trial(models.Model): 

    trial_start = DurationField() 
    movement_start = DurationField() 
    trial_stop = DurationField() 


    def clean(self): 
     from django.core.exceptions import ValidationError 
     if not (self.movement_start >= self.trial_start): 
      raise ValidationError('movement start must be >= trial start') 
     if not (self.trial_stop >= self.movement_start): 
      raise ValidationError('trial stop must be >= movement start') 
     if not (self.trial_stop > self.trial_start): 
      raise ValidationError('trial stop must be > trial start') 

My clean() yöntem kontrol olup olmadığı. Kullanıcı bir alanı doldurmayı unutursa, örn. Orijinal clean() fonksiyon yakalamak gerektiğini beri

can't compare datetime.timedelta to NoneType

Ben, bu hatayı alıyorum şaşırdığımı giriş eksik (bütün movement_start zorunlu bir alandır sonra): movement_start, sonra bir hata alıyorum. Öyleyse, eksik değerleri temel olarak nasıl kontrol edebilirim ve değerlerim belirli aralıklarda olup olmadığını nasıl kontrol edebilirim? Bu, modelin clean() yöntemiyle yapılabilir mi, yoksa Forms mu kullanmalıyım?

Edit1

daha net yapmak için: trial_start, movement_start ve trial_stop gerekli tüm alanlardır. Önce, tüm üç alanın doldurulduğunu kontrol eden ve değerlerin belirli bir aralıkta olup olmadığını kontrol eden bir clean()10 yöntemini yazmam gerekiyor.

Aşağıdaki kod örneğin, trial_start boş olabileceğinden, çalışmıyor. Her alanın varlığını kontrol etmek zorunda kalmak istemiyorum - django bunu benim için yapmalı.

class TrialForm(ModelForm): 

    class Meta: 
     model = Trial 

    def clean_movement_start(self): 
     movement_start = self.cleaned_data["movement_start"] 
     trial_start = self.cleaned_data["trial_start"] 
     if not (movement_start >= trial_start): 
      raise forms.ValidationError('movement start must be >= trial start') 
     return self.cleaned_data["movement_start"] 

EDIT2 Ben modelin clean() yöntemine bu çeki eklemek istedim nedeni piton kabuğu üzerinde oluşturulan nesneler, otomatik olarak doğru değerleri için kontrol edilebilir olmasıdır. Bir form görünümler için iyi olacak, ancak kabuk için de değer kontrolüne ihtiyacım var.

+0

gerekli alanları yapmak için 'boş = FALSE ekle: doğrulama)

(not ModelForms aynı zamanda çeşitli doğrulama adımlar var ve manken full_clean arayacak geçeceğiz. –

+0

@BurhanKhalid alanları zorunludur. 'blank = False 'varsayılan değerdir. – memyself

+0

@JonasGeiregat bu yüzden Forms'u kullanmalıyım? – memyself

cevap

6

Bunu gitmek için yol olduğunu tahmin: Ben formu ile nesneleri oluşturursanız

class TrialForm(ModelForm): 

    class Meta: 
     model = Trial 

    def clean(self): 

     data = self.cleaned_data 
     if not ('movement_start' in data.keys() and 'trial_start' in data.keys() and 'trial_stop' in data.keys()): 
      raise forms.ValidationError("Please fill out missing fields.") 

     trial_start = data['trial_start'] 
     movement_start = data['movement_start'] 
     trial_stop = data['trial_stop'] 

     if not (movement_start >= trial_start): 
      raise forms.ValidationError('movement start must be >= trial start') 

     if not (trial_stop >= movement_start): 
      raise forms.ValidationError('trial stop must be >= movement start') 

     if not (trial_stop > trial_start): 
      raise forms.ValidationError('trial stop must be > trial start') 

     return data 

DÜZENLEME Bu yaklaşımın dezavantajı, bu değer denetlemesi yalnızca çalışacaktır edilir. Python kabuğunda oluşturulan nesneler kontrol edilmeyecektir.

0

Benzer bir sorunla uğraşıyorum ama ForeignKey ile. Senin durumunda, sadece alanlar boş olmadığını kontrol ediyorum ve senin Boole ifadeleri basitleştirmek olacaktır: Ben bu geç olduğunu biliyorum

class Trial(models.Model): 

    trial_start = DurationField() 
    movement_start = DurationField() 
    trial_stop = DurationField() 


    def clean(self): 
     from django.core.exceptions import ValidationError 
     if self.trial_start: 
      if self.movement_start and self.movement_start < self.trial_start: 
       raise ValidationError('movement start must be >= trial start') 
      if self.trial_stop: 
       if self.trial_stop <= self.trial_start: 
        raise ValidationError('trial stop must be > trial start') 
       if self.movement_start: 
        if self.trial_stop < self.movement_start: 
         raise ValidationError('trial stop must be >= movement start') 
2

, ancak bu burada sona insanlar için neler olabileceğini niçin cevap : "Orijinal temiz" yoktur. Temiz yöntem, özel doğrulama için bir kancadır, bu yüzden kodunu sağlayan sizsiniz. OP'nin temiz kancayı nasıl kullandığını bilmediğinden emin olun, ancak: Bunu tanımladıktan sonra, Django'nun bütünüyle model doğrulamasını çalıştırması için full_clean() modelinizi çağırmalısınız.Farklı doğrulama yöntemlerini çağırdığı siparişin belgelerine bakın ve https://docs.djangoproject.com/en/1.11/ref/models/instances/#validating-objects (belki de önemli not: full_clean() otomatik olarak bir modelin save() tarafından çağrılmıyor, bu nedenle kabuğu kullanırken ve hemen kaydetme nedeninin bir parçasıdır) https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/#validation-on-a-modelform)

İlgili konular