为什么我的引用在Python中是动态的?为什么要从列表中删除对象?

时间:2014-04-18 19:03:48

标签: python django

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>&nbsp;</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>&nbsp;</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会像这样行事(或者我正在做什么导致它这样做!)

此外,我总是乐于接受有关如何使代码更好的建议。尽你所能,我需要学习。

非常感谢!

1 个答案:

答案 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每次迭代都会缩短一个元素。