Python 如何测试mptt模型?
这是我在django测试中的第一步 我在当前情况下测试的内容: 我在我的项目中使用MPTT,当创建新实例时,它的父实例将获得日期字段的新值 问题是什么: 在TestCase的setUp方法中创建实例后,TreeNode.objects.get()找不到已创建的实例,或者django看不到三个实例,或者我不知道会发生什么,但在底部的TreeNode.save()中描述的创建新子级不起作用 例如Python 如何测试mptt模型?,python,django,Python,Django,这是我在django测试中的第一步 我在当前情况下测试的内容: 我在我的项目中使用MPTT,当创建新实例时,它的父实例将获得日期字段的新值 问题是什么: 在TestCase的setUp方法中创建实例后,TreeNode.objects.get()找不到已创建的实例,或者django看不到三个实例,或者我不知道会发生什么,但在底部的TreeNode.save()中描述的创建新子级不起作用 例如 TreeNode.objects.create(id=4, parent_id=1) TreeNode
TreeNode.objects.create(id=4, parent_id=1)
TreeNode.objects.get(id=4).level(mptt中的autofield)等于None,但如果实例没有父项,则必须为0;如果父项存在,则必须为level+1。有时TreeNode.objects.get(id=4)根本找不到由TreeNode.objects.create(id=4)创建的对象
目标:定义OK方法以创建一个子节点,该子节点将合同日期、id和父节点作为属性,并在TreeNode.objects.create之后按原样运行save()
有很多问题,我想得到其中一部分的答案。主要问题是:
如何在测试中(或者在模型中,如果我做错了什么的话)创建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)
类树节点(MPTTModel):
account=models.OneToOneField(用户,unique=True,verbose_name='Аааааааааааа
#合同
id=models.CharField(详细名称=id',最大长度=10,主键=True)
parent=treeforeingkey('self',verbose\u name='IDППцицаааааааааааа
合同日期=models.DateField(null=False,blank=False)
invite\u period\u expire\u date=models.DateField(null=True,blank=True)
def是父母奖励的(自我,行):
如果行为else self,则返回getattr(self,self.pawarded_parents_fields[line-1])
def get_上级_级别(自我,级别):
如果self.get_level()-level>=0:
返回self.get\u().get(level=self.get\u level()-level)
一无所获
def get_相对等级(仅限自我、等级、新手):
结果=self.get\u后代().filter(级别=self.get\u级别()+级别)
如果只是新手(u):
结果=过滤器(λx:非x。是否父级奖励(级别),结果)
返回结果
def支付给父母(自我、行、每个周期五个):
父项=自身。获取\u级别(行)的\u父项\u
如果是家长:
从payments.models导入公司ClientPayment
如果行==1:
payment=CompanyClientPayment.objects.create(客户端=父级,使用\日期=self.contract\日期,
总价=价格[0][1]
如果每个周期五个
其他价格[0][0])
elif行==2:
payment=CompanyClientPayment.objects.create(客户端=父级,使用\日期=self.contract\日期,
总价=价格[1][1]
如果每个周期五个
其他价格[1][0])
elif行==3:
payment=CompanyClientPayment.objects.create(客户端=父级,
使用\日期=自我合同\日期
如果self.contract\u date.day是这样,我的问题是我认为如果对象已经存在,instance.save()
会进行“更新”查询。我错了。因为调用“更新”查询instance.update(*kwargs)
方法应该被调用。对不起,我是个茶壶。为什么要将id定义为字符域而不是使用默认的自动递增整数?每个客户都有一个由公司生成的id。它包括国家代码。因此,我使用自定义id域而不是自动递增id。