在 Django 中使用 fullCalendar
Using fullCalendar in Django
这里发布的问题的一些跟进 (),但自从提出这个问题后,我决定采取不同的方法。正如你所知道的,我是一个新手,所以请放轻松。
我想要在我的 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。展望未来,我知道我必须为 AJAX 视图修改我的 views.py
并为日历创建一个模板,但我不知道该怎么做。我的模板目前看起来像这样:
<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 等)但我不确定如何从这里开始。
任何帮助,尤其是代码片段方面的帮助,我们将不胜感激。
谢谢!
编辑:所以我能够使用以下代码加载日历:
// 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'
,它仍然显示带有周末的日历,所以当涉及到布尔值时,日历显然没有正确配置。我不确定为什么,因为其他配置设置(例如 header
、defaultView
和 firstDay
)似乎都运行良好。
2) 我使用 OrderedDict() 因为我怀疑在尝试将 events
加载到日历时顺序很重要,但我不确定这是否属实。我可以只使用普通的 Python 字典吗?
下面是您需要执行的操作的基本概述。创建一个 returns JSON 数据的视图,如完整日历所期望的那样。这很容易做到。您可以使用 JsonResponse 或使用 Django Rest Framework 手动创建一个自定义的。除非你要创建一个整体 API,否则我会使用 JsonResponse。
关于JsonResponse的格式,需要同时指定start
和title
。您可以在此处的完整日历 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 应用程序中显示每周日历,以显示数据库中的班次。以下是 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。展望未来,我知道我必须为 AJAX 视图修改我的 views.py
并为日历创建一个模板,但我不知道该怎么做。我的模板目前看起来像这样:
<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 等)但我不确定如何从这里开始。
任何帮助,尤其是代码片段方面的帮助,我们将不胜感激。
谢谢!
编辑:所以我能够使用以下代码加载日历:
// 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'
,它仍然显示带有周末的日历,所以当涉及到布尔值时,日历显然没有正确配置。我不确定为什么,因为其他配置设置(例如 header
、defaultView
和 firstDay
)似乎都运行良好。
2) 我使用 OrderedDict() 因为我怀疑在尝试将 events
加载到日历时顺序很重要,但我不确定这是否属实。我可以只使用普通的 Python 字典吗?
下面是您需要执行的操作的基本概述。创建一个 returns JSON 数据的视图,如完整日历所期望的那样。这很容易做到。您可以使用 JsonResponse 或使用 Django Rest Framework 手动创建一个自定义的。除非你要创建一个整体 API,否则我会使用 JsonResponse。
关于JsonResponse的格式,需要同时指定start
和title
。您可以在此处的完整日历 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)