Stack Overflow是我的Q& A圣经,所以首先,非常感谢你们所有人的贡献。作为开发人员,你们都让我的生活变得更轻松,为我节省了很多时间。
我想在我的问题前面说我对Python一般都是新手,我主要来自Java编程的背景。我的代码中可能存在很多问题,因为我仍在学习Python的怪癖。请温柔!
我正在使用Django创建一个事件管理应用程序,我遇到了某种引用问题。在下面的视图中,从应用程序中访问视图的那一天开始,每周创建一个事件列表。我正在创建表格的预格式化HTML行,然后显示在相应的模板中,并将其添加到列表中的每个“日期”对象。我知道这看起来很古老;为什么我不会在我的视图中使用JS来执行此操作?推理是我试图远离JS依赖于JS以使应用程序正常运行。
代码引用排序列表中的第一个和最后一个对象(事件),以确定最早事件的开始时间和最新事件的结束时间,这决定了在每个事件之前和之后放置了多少空白TD。事件,以及事件的colspan(持续时间)。在半小时的分辨率。但是,根据我模板中for循环的当前迭代,这些引用正在发生变化,由于某些原因我无法理解。我花了好几个小时试图解决这个问题,并尝试了许多不同的解决方案,但无济于事。
此外,我注意到我的事件列表的长度似乎每次迭代都减少了一次,好像一个'pop'函数自动发生......我不明白!
所有导入都是正确的,并包含在views.py的顶部。我认为没有必要包含它们。
功能:
def getWeekView(currDay): #currDay is simply datetime.now()
week_view = []
events = []
daily = list(Event.objects.filter(how_often='daily')) #copy querysets to lists to ease DB queries
weekly = list(Event.objects.filter(how_often='weekly'))
for day in xrange(0, 7, 1):
searchRange = [datetime(currDay.year, currDay.month, currDay.day, 0, 0, 0), datetime(currDay.year, currDay.month, currDay.day, 23, 59, 59)]
events = list(Event.objects.filter(date__range=searchRange, is_repeat=False))
for event in daily: #copy recurring events into events list
if is_open(event.business, currDay.isoweekday()):
events.append(event)
for event in weekly:
if (event.date).isoweekday() == currDay.isoweekday() and is_open(event.business, currDay.isoweekday()):
events.append(event)
events = sorted(events, key=lambda event: (event.date).time())
if len(events) > 0:
earliest_time = (events[0].date).time()
latest_time = (events[len(events)-1].end).time()
earliest = Decimal(earliest_time.hour) + (Decimal(earliest_time.minute)/60)
latest = Decimal(latest_time.hour) + (Decimal(latest_time.minute)/60)
blocks = []
x = earliest
while x <= latest:
if x % 1 != 0:
blocks.append("%s:%s" % (str(int(floor(x))), '30'))
else:
blocks.append("%s:%s" % (str(int(x)), '00'))
x = x+Decimal(0.5)
for event in events:
end_time = (event.end).time()
start_time = (event.date).time()
end = Decimal(end_time.hour) + (Decimal(end_time.minute)/60)
start = Decimal(start_time.hour) + (Decimal(start_time.minute)/60)
duration = (end - start)*2 #multiply by two for 1/2hr resolution in the resultant table
temp = "<tr>"
x = earliest
while x < start:
temp = "%s%s" % (temp, "<td> </td>")
x = x+Decimal(0.5)
if duration > 1:
# I changed this to output variables for the purposes of debugging the issue. Normally the commented line underneath this would apply.
temp += """<td colspan="%s">earliest_time:%s latest_time:%s earliest:%s latest:%s start:%s end:%s duration:%s x:%s len of events:%s</td>""" % (int(duration), earliest_time, latest_time, earliest, latest, start, end, duration, x, len(events))
#temp += """<td colspan="%s"><a href="%s">%s</a></td>""" % (int(duration), reverse('event_detail', args=[event.pk]),event.title)
else:
temp += """<td><a href="%s">%s</a></td>""" % (reverse('event_detail', args=[event.pk]),event.title)
x += duration
while x < latest:
temp += '<td> </td>'
x += Decimal(0.5)
temp += '</tr>'
event.row = temp
week_view.append({'day':currDay.strftime('%a, %x'), 'events':events, 'blocks':blocks})
else:
week_view.append({'day':currDay.strftime('%a, %x')})
currDay += timedelta(days=1)
return week_view
示例文字输出:
Fri, 04/18/14
3:00 3:30 4:00 4:30 5:00 5:30 6:00 6:30 7:00 7:30
earliest_time:03:00:00 latest_time:07:30:00 earliest:3 latest:7.5 start:3 end:5.5 duration:5.0 x:3 len of events:2
earliest_time:05:30:00 latest_time:07:30:00 earliest:5.5 latest:7.5 start:5.5 end:7.5 duration:4.0 x:5.5 len of events:1
Sat, 04/19/14
5:30 6:00 6:30 7:00 7:30
earliest_time:05:30:00 latest_time:07:30:00 earliest:5.5 latest:7.5 start:5.5 end:7.5 duration:4.0 x:5.5 len of events:1
Sun, 04/20/14
No Events Listed
Mon, 04/21/14
5:30 6:00 6:30 7:00 7:30
earliest_time:05:30:00 latest_time:07:30:00 earliest:5.5 latest:7.5 start:5.5 end:7.5 duration:4.0 x:5.5 len of events:1
Tue, 04/22/14
5:30 6:00 6:30 7:00 7:30
earliest_time:05:30:00 latest_time:07:30:00 earliest:5.5 latest:7.5 start:5.5 end:7.5 duration:4.0 x:5.5 len of events:1
Wed, 04/23/14
5:30 6:00 6:30 7:00 7:30
earliest_time:05:30:00 latest_time:07:30:00 earliest:5.5 latest:7.5 start:5.5 end:7.5 duration:4.0 x:5.5 len of events:1
Thu, 04/24/14
5:30 6:00 6:30 7:00 7:30
earliest_time:05:30:00 latest_time:07:30:00 earliest:5.5 latest:7.5 start:5.5 end:7.5 duration:4.0 x:5.5 len of events:1
相关的Django模型:
class Event(models.Model):
DAILY = 'daily'
WEEKLY = 'weekly'
REPEAT_CHOICES = (
(DAILY, 'Daily'),
(WEEKLY, 'Weekly'),
)
title = models.CharField(max_length=25, help_text="Please enter the name of your event")
description = models.CharField(max_length=255, help_text="Please enter a description of your event")
date = models.DateTimeField(help_text="Please select the date and start time of your event")
end = models.DateTimeField(help_text="Please select the end time / date that your event will finish")
business = models.ForeignKey(Business)
category = models.ManyToManyField(Category, help_text="Please select the category(ies) of your event")
is_repeat = models.BooleanField(default=False, help_text="Please select whether your event will repeat")
how_often = models.CharField(max_length=7, blank=True, choices=REPEAT_CHOICES, help_text="Please select how often your event will repeat")
def __unicode__(self):
return unicode(self.title)
负责迭代周对象并输出到浏览器的模板中的代码:
<div>
<table id="index-table">
<tr><th>Date</th><th>Events</th></tr>
{% for day in week_obj %}
<tr><td>{{ day.day }}</td>
<td>{% if day.events %}<table id="events-table{{ forloop.counter }}" class="table"><tbody><tr>{% for block in day.blocks %}<th>{{ block }}</th>{% endfor %}{% for event in day.events %}{{ event.row|safe }}{% endfor %}</tbody></table>{% else %}No Events Listed{% endif %}</td>
</tr>
{% endfor %}
</table>
</div>
我非常感谢任何人可以提供的任何帮助。我最为困惑,我想理解为什么Python会像这样行事(或者我正在做什么导致它这样做!)
此外,我总是乐于接受有关如何使代码更好的建议。尽你所能,我需要学习。
非常感谢!
答案 0 :(得分:2)
具有实际Django经验的其他人可以帮助解决一般性问题。在任何情况下,关于你的直接问题:
for day in xrange(0, 7, 1):
searchRange = [datetime(currDay.year, currDay.month, currDay.day, 0, 0, 0), datetime(currDay.year, currDay.month, currDay.day, 23, 59, 59)]
events = list(Event.objects.filter(date__range=searchRange, is_repeat=False))
# etc.
currDay += timedelta(days=1)
在每次迭代开始时,使用过滤前一天定义的过滤器重新定义events
(在迭代结束时更新为currDay
)。因此,events[0]
更改,events
每次迭代都会缩短一个元素。