【问题标题】:Using fullCalendar in Django在 Django 中使用 fullCalendar
【发布时间】:2015-07-20 00:15:09
【问题描述】:

对此处发布的问题 (Django: modifying data with user input through custom template tag?) 进行了一些跟进,但自从提出这个问题后,我决定采用不同的方法。如您所知,我是新手,所以请放轻松。

我想要在我的 Django 应用程序中显示数据库中的班次的每周日历。以下是 Shift 模型。

class Shift(models.Model):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='shifts',
        blank=True, null=True) # A shift may not have an owner.

    # Choices for fields. Add more choices as necessary.
    DAYS = (
        ('M', 'Monday'),
        ('TU', 'Tuesday'),
        ('W', 'Wednesday'),
        ('TH', 'Thursday'),
        ('F', 'Friday'),
        ('SA', 'Saturday'),
        ('SU', 'Sunday'),
    )

    day_of_the_week = models.CharField(max_length=2, choices=DAYS, blank=True, null=True)
    start_date = models.DateField(blank=True, null=True)
    end_date = models.DateField(blank=True, null=True)
    start_time = models.TimeField(default='12:00:00')
    end_time = models.TimeField(default='14:00:00')
    hours = models.DurationField(editable=False)
    activated = models.BooleanField(verbose_name='Activate', default=False)
    sale_status = models.BooleanField(verbose_name='Activate sale', default=False)

    ...

    def save(self, *args, **kwargs): # Overwrite save() to calculate and save the duration of a shift.
        temp_date = datetime(1,1,1,0,0,0)
        self.hours = datetime.combine(temp_date, self.end_time) - datetime.combine(temp_date, self.start_time)
        super(Shift, self).save(*args, **kwargs)

管理员创建班次并将所有者分配给班次。分配所有者后,所有者可以出售班次,这会将 sale_status=False 更改为 sale_status=True。然后其他用户可以购买班次,将班次的owner更改为买家,将班次的sale_status更改为False。理想情况下,这些操作(销售和购买班次)可以通过日历通过单击班次来执行。这意味着日历必须显示activated=True 的所有班次。

我已经研究了一段时间,并决定使用FullCalendar。展望未来,我知道我必须修改我的 views.py 以获得 AJAX 视图并为日历创建模板,但我也不知道该怎么做。我的模板目前看起来像这样:

<head>
<link rel='stylesheet' href='fullcalendar/fullcalendar.css' />
<script src='lib/jquery.min.js'></script>
<script src='lib/moment.min.js'></script>
<script src='fullcalendar/fullcalendar.js'></script>
</head>

<div id="calendar"></div>
<script type='text/javascript'>
$(document).ready(function() {

    // page is now ready, initialize the calendar...

    $('#calendar').fullCalendar({
        // put your options and callbacks here
        events: "shifts/eventsFeed",
        weekends: false,
        editable: false,
    })

});
</script>

这显然是错误的(没有使用 Django 的模板语言,eventsFeed 没有实现等)但是我不知道从这里怎么走。

任何帮助,尤其是关于 sn-ps 代码的帮助,将不胜感激。

谢谢!

编辑:所以我能够使用以下代码加载日历:

// in views.py
def view_shifts(request):
    """
    View for displaying activated shifts in a weekly calendar format.
    """

    activated_shifts = Shift.objects.filter(activated=True) # Get all the activated shifts.
    shifts = [] # place holder
    for shift in activated_shifts:
        temp = OrderedDict()
        temp['id'] = shift.id
        temp['title'] = shift.title
        temp['start'] = str(shift.start_date) + 'T' + str(shift.start_time)
        temp['end'] = str(shift.end_date) + 'T' + str(shift.end_time)
        shifts.append(temp)

    calendar_config_options = {'header': {
                                    'left': 'prev,next today',
                                    'center': 'title',
                                    'right': 'month,agendaWeek,agendaDay'
                                },
                               'defaultView': 'agendaWeek',
                               'editable': 'True', # View only.
                               'events': json.dumps(shifts),
                               'firstDay': 1 # Week starts on Monday.
                               }

    return render(request, 'shifts/full_calendar.html', {'calendar_config_options': calendar_config_options})

我还将字段title 添加到我的Shift。它只是self.owner 的字符串表示形式。 我的模板名为calendar_init.html,如下:

<script type="text/javascript">
    $(document).ready(function() { // Page is ready.
        // Initialize the calendar.
        $('#calendar').fullCalendar({{ calendar_config_options }});
    });
</script>

现在,当模板被渲染时,我得到以下信息:

<!DOCTYPE html>
<head>

    <title>Shifts</title>

    ...

    <script type="text/javascript">
    $(document).ready(function() { // Page is ready.
        // Initialize the calendar.
        $('#calendar').fullCalendar({'firstDay': 1, 'header': {'right': 'month,agendaWeek,agendaDay', 'center': 'title', 'left': 'prev,next today'}, 'defaultView': 'agendaWeek', 'editable': True, 'events': '[{"id": 61, "title": "Unclaimed", "start": "2015-07-21T14:00:00", "end": "2015-07-21T16:00:00"}, {"id": 62, "title": "slee17", "start": "2015-07-21T12:00:00", "end": "2015-07-21T14:00:00"}]'});
    });
</script>

</head>

<body>
<div id="calendar"></div>

但是,日历仍然没有加载班次。我尝试使用json.loads(json.dumps(shifts)) 而不是json.dumps(shifts),还尝试使用http://robotfantastic.org/serializing-python-data-to-json-some-edge-cases.html 中的辅助函数。两者都没有在日历上加载班次。我在这里做错了什么? (日历还在加载中,它的配置和我配置的一样,但是日历是空的。)

另外,还有两个小问题: 1) 当我说'edtiable': True 而不是'editable': 'True' 时,页面变为空白,没有错误。为什么会这样?我也尝试过'weekends'='False',它仍然显示带有周末的日历,因此在布尔值方面显然没有正确配置日历。我不知道为什么,因为其他配置设置(例如headerdefaultViewfirstDay)似乎都运行良好。 2) 我使用 OrderedDict() 是因为我怀疑在尝试将 events 加载到日历时顺序很重要,但我不确定这是否属实。我可以只使用普通的 Python 字典吗?

【问题讨论】:

    标签: python django django-views fullcalendar


    【解决方案1】:

    以下是您需要执行的操作的基本概述。创建一个按完整日历预期返回 JSON 数据的视图。这很简单。您可以使用JsonResponse 手动创建一个自定义或使用 Django Rest Framework。除非您要创建一个完整的 API,否则我会使用 JsonResponse。

    JsonResponse 的格式需要同时指定starttitle。您可以在完整日历的docs 中找到其他可能的字段。

    例子:

    from django.http import JsonResponse
    
    def example(request):
        data = [
            {
                'title': 'event1',
                'start': '2010-01-01'
            },
            {
                'title': 'event2',
                'start': '2010-01-05',
                'end': '2010-01-07'
            }
        ]
        return JsonResponse(data, safe=False)
    

    【讨论】:

    • 非常感谢!我已经听从了你的建议(稍微调整了细节以使用 Django 的模板,但仍然是相同的想法),现在我遇到了新问题。我也编辑了这个问题,但知道为什么我的日历不会从数据库中加载事件吗?
    • 您似乎没有遵循我的答案的设计。您编辑的方法没有使用 AJAX,它只是在第一次加载视图时提供所有数据。请不要尝试创建值字典以传递给完整日历的初始化程序。避免这种情况应该会引导您自己回答新问题。
    • 我在这里可能错了,但我看不出你的方法和我的方法有什么区别(至少从代码 sn-p 来看),特别是因为我不明白你的代码是如何使用的阿贾克斯。另外,我希望日历首先显示数据库中的所有班次,所以我不想在第一次加载视图时提供所有数据吗?我知道我想在用户 buysell 轮班时使用 AJAX,但这是为了以后,一旦所有轮班都显示在日历中。如果我错了,请随时纠正我。
    猜你喜欢
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    • 2017-01-12
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多