2017-04-04 45 views
1

我在models.py以下模型:的Django模型字段驗證沒有引發異常,因爲它應該

@python_2_unicode_compatible 
class Session(ModelCommon): # ModelCommon is an abstract Model which extends from models.Model with the fields name(CharField) and enabled(BooleanField). 
    """ 
    Model Session with foreign key to Model Event. 
    """ 
    event = models.ForeignKey(verbose_name=_('Event'), to=Event, default=None, null=False, blank=False) 
    start_datetime = models.DateTimeField(verbose_name=_('Session Starts'), default=None, null=False, blank=False) 
    end_datetime = models.DateTimeField(verbose_name=_('Session Ends'), default=None, null=False, blank=False) 
    available = models.BooleanField(verbose_name=_('Available'), default=True, null=False, blank=False) 
    price = models.DecimalField(verbose_name=_('Price'), max_digits=10, decimal_places=2, 
           validators=[MinValueValidator(0.00)], 
           default=None, null=False, blank=False) 

當我測試模型,它不應該被保存在數據庫中,如果price爲負,則不會像應該那樣引發異常。

test_models.py

class SessionTestCase(TestCase): 
    """ 
    Case of tests for Model Session. 
    """ 

    def setUpTestData(cls): 
     """ 
     This method is used to declare dummy data that could be used by all tests. 
     """ 
     cls.test_event = Event(name='Test Event Name for Session', enabled=True) 
     cls.test_event.save() 

    def setUp(self): 
     """ 
     This method is used to run code before each test. 
     """ 
     self.session = Session(event=self.test_event, name='Session No1', enabled=True, 
           start_datetime=timezone.now() + timedelta(days=1), 
           end_datetime=timezone.now() + timedelta(days=3), price=0) 


    def test_session_price_cannot_be_negative(self): 
     """ 
     :return: Passed if Session object with negative price raises Exception. 
     """ 
     self.session.price = -20.0 
     self.assertRaises(Exception, lambda: self.session.save()) 

最後,當我跑我test_models.py,我得到以下信息:

Failure 
Traceback (most recent call last): 
    self.assertRaises(Exception, lambda: self.session.save()) 
AssertionError: Exception not raised 

回答

0

調用save()不會觸發驗證。有關更多信息,請參閱validating objects上的Django文檔。您可以改爲撥打full_clean

self.session.price = -20.0 
self.assertRaises(Exception, lambda: self.session.full_clean()) 

請注意,您可以從代碼中移除lambda並傳遞可調用對象。抓住更具體的ValidationError而不是Exception也會更好。

self.session.price = -20.0 
self.assertRaises(ValidationError, self.session.full_clean) 
+0

這工作,謝謝。我覆蓋了我的模型中的save()方法,所以它包含'full_clean()'。我希望可以做到這一點。 – joaofguerreiro

+0

如果在save方法中調用'full_clean()',驗證有時會運行兩次。請參閱[這個問題](http://stackoverflow.com/questions/12945339/is-this-the-way-to-validate-django-model-fields/12945692#12945692)瞭解更多信息。 – Alasdair