在 Django 中使用 fullCalendar [英] Using fullCalendar in Django

查看:70
本文介绍了在 Django 中使用 fullCalendar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里发布的问题的一些后续行动(Django:通过自定义模板标签使用用户输入修改数据?),但自从提出这个问题后,我决定采取不同的方法.正如你所知道的,我是一个新手,所以请放轻松.

Somewhat of a follow-up to the question posted here (Django: modifying data with user input through custom template tag?), but since asking the question I've decided to take a different approach. As you can tell I'm a newb so please go easy.

我想在我的 Django 应用程序中使用一个周历来显示数据库中的班次.以下是Shift模型.

I want a weekly calendar in my Django app that displays shifts in the database. Following is the Shift model.

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 的所有班次.

An admin creates shifts and assigns owners to the shifts. Once an owner is assigned, the owner can sell the shift, which will change sale_status=False to sale_status=True. Then other users can buy the shift, changing the owner of the shift to the buyer and the shift's sale_status to False. Ideally, these actions (selling and buying shifts) can be performed through the calendar, by clicking on a shift. That means the calendar has to display all the shifts whose activated=True.

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

I've been digging into this for a while now and decided to use FullCalendar. Going forward, I know I have to modify my views.py for an AJAX view and create a template for the calendar, but I am not sure how to do either. My template currently looks like this:

<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 等)但我不知道如何从这里开始.

This is obviously wrong (does not use Django's template language, eventsFeed is not implemented, etc.) but I'm not sure how to go from here.

任何帮助,尤其是代码片段,将不胜感激.

Any help, especially with snippets of code, will be greatly appreciated.

谢谢!

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

Edit: So I was able to get the calendar to load with following codes:

// 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,如下所示:

I also added the field title to my Shift. It is simply the string representation of self.owner. My template, called calendar_init.html, is as following:

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

现在,当模板呈现时,我得到以下信息:

Now, when the template is rendered, I get the following:

<!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.两者都没有加载轮班日历.我在这里做错了什么?(日历还在加载中,它的配置和我配置的一样,但是日历是空的.)

However, the calendar is still not loaded with shifts. I've tried using json.loads(json.dumps(shifts)) instead of json.dumps(shifts) and have also tried using the helper functions from http://robotfantastic.org/serializing-python-data-to-json-some-edge-cases.html. Neither have loaded the calendar with shifts. What am I doing wrong here? (The calendar is still being loaded, its configuration is as I have configured, but the calendar is empty.)

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

Also, two small questions: 1) when I say 'edtiable': True instead of 'editable': 'True', the page goes blank, with no errors. Why is this so? I've also tried doing 'weekends'='False', which still shows the calendar with weekends, so the calendar clearly isn't being configured right when it comes to booleans. I'm not sure why though, since other configuration settings (e.g. header, defaultView, and firstDay) all seemed to have worked fine. 2) I used OrderedDict() because I had a suspicion that the order matters when trying to load events to the calendar, but I'm not sure if this is true. Could I just use a regular Python dictionary?

推荐答案

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

Here's a basic overview of what you need to do. Create a view that returns the JSON data as full calendar expects it. This is pretty simple to do. You can create a custom one by hand with JsonResponse or use Django Rest Framework. Unless you're creating a whole API, I'd go with using JsonResponse.

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

As for the format of the JsonResponse, you need to specify both start and title. You can find the other possible fields here in full calendar's 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 中使用 fullCalendar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆