2014-11-15 3 views
0

Есть мои первые шаги в тестировании django.Как проверить модель mptt?

Что тестирование в данном случае:

Я использую MPTT в моем проекте и при создании нового экземпляра - это родительский экземпляр получения нового значения поля даты.

Что такое проблема:

после создания экземпляров в методе нАлАдкИ в TestCase, TreeNode.objects.get() не может найти созданный экземпляр или Джанго не видит три или я не знаю, что происходит, но создание нового дочернего элемента, описанного в TreeNode.save(), не работает.

Для exapmple после

TreeNode.objects.create(id=4, parent_id=1) 

TreeNode.objects.get (ID = 4) .level (AutoField в mptt) не равен None, но должно быть равно 0, если экземпляр не имеют родителя или parent.level + 1, если родитель существует. Иногда TreeNode.objects.get (id = 4) просто не может найти объект, который был создан TreeNode.objects.create (id = 4).

Цель: определить метод OK для создания дочернего узла, который принимает contract_date, id и parent как атрибуты и после TreeNode.objects.create running save() as is.

Есть много вопросов, и я хотел бы получить ответы на них. Основные вопросы:

Как создать объект TreeNode в тесте (или в модели, если я что-то не так)? Как правильно определить объект как дочерний элемент другого TreeNode?

Мой код:

Тесты:

# method for creating a newbie. 
def instantiate_treenode(uid, contract_date, parent_id=None): 
TreeNode.objects.create(id=uid, 
           contract_date=contract_date, 
           date_of_birth=date.today(), 
           account_id=uid, 
           identity_expire_date=date.today(), 
           parent=TreeNode.objects.get(id=parent_id) if parent_id else None,) 


class BigTestTree(TestCase): 
# 
# 
# 
#  # 
##### # 
def setUp(self): 
    instantiate_treenode(uid=1, contract_date=date(2014, 1, 1)) 

    instantiate_treenode(uid=2, contract_date=date(2014, 1, 2), parent_id=1) 

    instantiate_treenode(uid=3, contract_date=date(2014, 1, 3), parent_id=2) 

    instantiate_treenode(uid=4, contract_date=date(2014, 1, 4), parent_id=3) 
    instantiate_treenode(uid=5, contract_date=date(2014, 1, 5), parent_id=3) 

    instantiate_treenode(uid=6, contract_date=date(2014, 1, 6), parent_id=4) 
    instantiate_treenode(uid=7, contract_date=date(2014, 1, 7), parent_id=4) 
    instantiate_treenode(uid=8, contract_date=date(2014, 1, 8), parent_id=4) 
    instantiate_treenode(uid=9, contract_date=date(2014, 1, 9), parent_id=4) 

    for i in range(1, 10): 
     self.assertEqual(TreeNode.objects.get(id=i).paid_income, 0) 

def test_add_newbies_to_fourth_line(self): 

    instantiate_treenode(uid=11, contract_date=date(2014, 1, 10), parent_id=5) 

    self.assertEqual(TreeNode.objects.get(id=1).expected_income, 5 * 550) 
    self.assertEqual(TreeNode.objects.get(id=2).paid_income, 5 * 1000) 

    for i in range(3, 10): 
     self.assertEqual(TreeNode.objects.get(id=i).paid_income, 0) 

    self.assertEqual(TreeNode.objects.get(id=7).is_parent_rewarded(3), True) 
    self.assertEqual(TreeNode.objects.get(id=7).is_parent_rewarded(1), False) 

    instantiate_treenode(uid=10, contract_date=date(2014, 1, 10), left=13, right=14, lvl=4, 
         parent_id=4) 

    self.assertEqual(TreeNode.objects.get(id=1).paid_income, 5 * 550) 
    self.assertEqual(TreeNode.objects.get(id=2).paid_income, 5 * 1000) 
    self.assertEqual(TreeNode.objects.get(id=3).paid_income, 5 * 3500) 
    self.assertEqual(TreeNode.objects.get(id=4).paid_income, 5 * 5400) 

    for i in range(5, 10): 
     self.assertEqual(TreeNode.objects.get(id=i).paid_income, 0) 

MPTT Модель

class TreeNode(MPTTModel): 

    account = models.OneToOneField(User, unique=True, verbose_name='Аккаунт') 

    # contract 
    id = models.CharField(verbose_name='ID', max_length=10, primary_key=True) 
    parent = TreeForeignKey('self', verbose_name='ID пригласившего', null=True, blank=True, related_name='child') 
    contract_date = models.DateField(null=False, blank=False) 

    invite_period_expire_date = models.DateField(null=True, blank=True) 

    def is_parent_rewarded(self, line): 
     return getattr(self, self.rewarded_parents_fields[line - 1]) if line else self 

    def get_parent_of_level(self, level): 
     if self.get_level() - level >= 0: 
      return self.get_ancestors().get(level=self.get_level() - level) 
     return None 

    def get_relative_level(self, level, newbies_only): 
     result = self.get_descendants().filter(level=self.get_level() + level) 
     if newbies_only: 
      result = filter(lambda x: not x.is_parent_rewarded(level), result) 
     return result 

    def pay_to_parent(self, line, five_per_period): 
     parent = self.get_parent_of_level(line) 
     if parent: 
      from payments.models import CompanyToClientPayment 

      if line == 1: 
       payment = CompanyToClientPayment.objects.create(client=parent, use_date=self.contract_date, 
                   total=prices[0][1] 
                   if five_per_period 
                   else prices[0][0]) 
      elif line == 2: 
       payment = CompanyToClientPayment.objects.create(client=parent, use_date=self.contract_date, 
                   total=prices[1][1] 
                   if five_per_period 
                   else prices[1][0]) 
      elif line == 3: 
       payment = CompanyToClientPayment.objects.create(client=parent, 
                   use_date=self.contract_date 
                   if self.contract_date.day <= 5 
                   else next_fifth_day_of_month(self.contract_date), 
                   total=prices[2]) 
      elif line == 4: 
       payment = CompanyToClientPayment.objects.create(client=parent, 
                   use_date=self.contract_date 
                   if self.contract_date.day <= 5 
                   else next_fifth_day_of_month(self.contract_date), 
                   total=prices[3]) 
      else: 

       raise ValueError('Invalid line to pay for invite') 

      #print('paymentID' + str(payment.id)) 
     setattr(self, self.rewarded_parents_fields[line - 1], True) 
     self.save() 
     parent.save() 
     # print getattr(self, self.rewarded_parents_fields[line-1]) 

    def close_invite_period(self, expired): 
     for child in filter(lambda x: x.contract_date <= self.invite_period_expire_date, 
          self.get_relative_level(level=1, newbies_only=True)): 
      child.pay_to_parent(1, five_per_period=not expired) 

      if child.get_parent_of_level(2): 
       child.pay_to_parent(2, five_per_period=not expired) 

     self.invite_period_expire_date = None 
     self.save() 

    def start_invite_period(self, start_date): 
     if self.invite_period_expire_date: 
      raise ReopeningInvitePeriodException 
     self.invite_period_expire_date = start_date + invite_period 
     self.save() 

    def save(self, *args, **kwargs): 

     if self.get_parent_of_level(1) and TreeNode.objects.filter(id=self.id).exists(): 
      if not self.get_parent_of_level(1).invite_period_expire_date: 
       self.get_parent_of_level(1).start_invite_period(self.contract_date) 
      elif self.get_parent_of_level(1).invite_period_expire_date <= self.contract_date: 
       self.get_parent_of_level(1).close_invite_period(expired=True) 
       self.get_parent_of_level(1).start_invite_period(self.contract_date) 

      newbie_brothers = self.get_parent_of_level(1).get_relative_level(level=1, newbies_only=True) 

      if len(newbie_brothers) == 5: 
       self.get_parent_of_level(1).close_invite_period(expired=False) 

      if self.get_parent_of_level(3): 
       newbie_brothers = self.get_parent_of_level(3).get_relative_level(level=3, newbies_only=True) 
       if len(newbie_brothers) == 5: 
        for newbie in newbie_brothers: 
         newbie.pay_to_parent(3, five_per_period=False) 

       if self.get_parent_of_level(4): 
        newbie_brothers = self.get_parent_of_level(4).get_relative_level(level=4, newbies_only=True) 
        if len(newbie_brothers) == 5: 
         for newbie in newbie_brothers: 
          newbie.pay_to_parent(4, five_per_period=False) 
     super(TreeNode, self).save(*args, **kwargs) 
+0

Почему вы определяете id как CharField, а не используете автоинкрементный int по умолчанию? –

+0

У каждого клиента есть идентификатор, созданный компанией. Он включает код страны. Из-за этого я использую поле пользовательского идентификатора вместо идентификатора autoincrement. – amazingbasil

ответ

0

Итак, моя проблема заключалась в том, что я думал, что 'обновление' запрос instance.save() делает, если объект уже существует. Я был неправ. Для вызова 'update' необходимо вызвать метод instance.update(*kwargs). Прости. Я чайник.

Смежные вопросы