我想创建一个任务列表,每个任务都有一个日期时间属性。任务需要按照t_created
为第一个,t_paid
为最后。订单显示在step_datetime
。每个任务的描述在STEPS
。Django models.py中的冗余代码。我如何改进它?
我目前有两种方法all_steps
和next_step
,它显示任务列表信息。这两种方法还需要显示user_created
的名称,但该变量在调用方法之前不会被定义。这就是为什么我正在做一个字符串replace
方法。
我觉得我很重复我的代码,我想遵循Django的DRY原则。有什么方法可以改进此代码?
这里是我的全码:
class Order(models.Model) :
def __unicode__(self) :
return unicode(self.id)
def comments_count(self) :
return OrderComment.objects.filter(order = self.id).count()
def all_steps(self) :
user = self.user_created.first_name
steps = []
step_datetime = [
self.t_created,
self.t_action,
self.t_followup_one,
self.t_vendor_appt_one,
self.t_vendor_appt_two,
self.t_work_done,
self.t_followup_two,
self.t_paid,
]
for (i, step) in enumerate(self.STEPS) :
steps.append((step_datetime[ i ], step.replace('<user_created>', user),))
return steps
def next_step(self) :
user = self.user_created.first_name
step = 0
if self.t_action is None :
step = 0
elif self.t_followup_one is None :
step = 1
elif self.t_vendor_appt_one is None :
step = 2
elif self.t_vendor_appt_two is None :
step = 3
elif self.t_work_done is None :
step = 4
elif self.t_followup_two is None :
step = 5
elif self.paid is None :
step = 6
return str(step) + ": " + self.STEPS[ step ].replace('<user_created>', user)
STEPS = [
"Review, then either approve or reject the order.",
"Follow up with <user_created>",
"Contact the vendor to get a quote and arrange an appointment for <user_created>.",
"Review the quote, (get owner approval), then arrange a second appointment for the repairs.",
"Confirm the finished repairs and pay the vendor.",
"Follow up again with <user_created>",
"Confirm payment and close the order.",
]
ACTION_CHOICES = (
('p', 'pending' ),
('a', 'approved'),
('r', 'rejected'),
('c', 'closed' ),
)
user_created = models.ForeignKey(User, related_name = 'user_created', verbose_name = 'created by')
user_action = models.ForeignKey(User, related_name = 'user_status' , verbose_name = 'action by' , null = True, blank = True)
t_created = models.DateTimeField(auto_now_add = True, verbose_name = 'created')
t_action = models.DateTimeField(null = True, blank = True, verbose_name = 'action' )
t_followup_one = models.DateTimeField(null = True, blank = True, verbose_name = 'first follow-up' )
t_vendor_appt_one = models.DateTimeField(null = True, blank = True, verbose_name = 'first appointment' )
t_vendor_appt_two = models.DateTimeField(null = True, blank = True, verbose_name = 'second appointment')
t_work_done = models.DateTimeField(null = True, blank = True, verbose_name = 'work done' )
t_followup_two = models.DateTimeField(null = True, blank = True, verbose_name = 'second follow-up' )
t_paid = models.DateTimeField(null = True, blank = True, verbose_name = 'paid' )
action = models.CharField(max_length = 1, choices = ACTION_CHOICES, default = 'p')
quote = models.DecimalField(max_digits = 8, decimal_places = 2, null = True, blank = True)
payment = models.DecimalField(max_digits = 8, decimal_places = 2, null = True, blank = True)
items = models.ManyToManyField(Item, null = True, blank = True)
t_modified = models.DateTimeField(auto_now = True, verbose_name = 'modified')
接受@Dougal's answer后。我改变了一些变数的周围,并用此想出了:
def all_steps(self) :
user = self.user_created.first_name
return [
(getattr(self, attr), task.format(user = user))
for (attr, task) in self.TASKS
]
def next_step(self) :
user = self.user_created.first_name
task_num = next(
(i for (i, (attr, task)) in enumerate(self.TASKS) if getattr(self, attr) is None),
None
)
if task_num == None :
return "Done!"
else:
return "{number}: {task}".format(
number = str(task_num + 1),
task = self.TASKS[ task_num ][ 1 ].format(user = user)
)
TASKS = (
("t_action" , "Review, then either approve or reject the order."),
("t_followup_one" , "Follow up with {user}."),
("t_vendor_appt_one", "Contact the vendor to get a quote and arrange an appointment for {user}."),
("t_vendor_appt_two", "Review the quote, (get owner approval), then arrange a second appointment for the repairs."),
("t_work_done" , "Confirm the finished repairs and pay the vendor."),
("t_followup_two" , "Follow up again with {user}."),
("t_paid" , "Confirm payment and close the order."),
)
那么我对'.replace('',user)'做了什么是最好的(或唯一的)方法? –
hobbes3
2012-03-08 18:37:03
@ hobbes3这当然不是唯一的方法,但我不知道更好的方法。一种替代方案可能是用例如'lambda s:“跟进%s。” %s'然后执行'self.STEPS [step](user)';这不是更好的海事组织,虽然它更灵活一点。这需要静态描述为'lambda'。你也可以在STEPS的原始字符串中使用'%(user_created)s',然后使用'self.STEPS [step]%{'user_created':user}';这可能比'.replace'方法好一点,我想。 – Dougal 2012-03-08 18:40:13
列表中的[(x,y)如何工作?它为for循环的每次迭代都执行'(x,y)'? – hobbes3 2012-03-08 21:11:08