장고 - django-fullcalendar 라이브러리 적용
- 이번 포스트에서는 django에서 fullcalendar 라이브러리를 적용하는 방법에 대해 알아볼 것이다.
ex) extore_project
1. fullcalendar 설치
- 경로 : extore_project 파일 위치
1
$ pip install -e git+https://github.com/rodrigoamaral/django-fullcalendar.git#egg=django-fullcalendar
2. INSTALLED_APPS에 fullcalendar 모듈 추가
- 경로 : config(프로젝트) > settings.py
1
2
3
4INSTALLED_APPS = (
...
'fullcalendar',
)
3. fullcalendar 파일 작성
- 경로 : schedule > fullcalendar.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27from django.conf import settings
FULLCALENDAR_DEFAULTS = {
'css_url': '//cdnjs.cloudflare.com/ajax/libs/fullcalendar/1.6.4/fullcalendar.css',
'print_css_url': '//cdnjs.cloudflare.com/ajax/libs/fullcalendar/1.6.4/fullcalendar.print.css',
'javascript_url': '//cdnjs.cloudflare.com/ajax/libs/fullcalendar/1.6.4/fullcalendar.min.js',
'jquery_url': '//code.jquery.com/jquery-3.4.1.min.js',
'jquery_ui_url': '//code.jquery.com/ui/1.10.4/jquery-ui.js',
}
FULLCALENDAR = FULLCALENDAR_DEFAULTS.copy()
FULLCALENDAR.update(getattr(settings, 'FULLCALENDAR', {}))
def css_url():
return FULLCALENDAR['css_url']
def print_css_url():
return FULLCALENDAR['print_css_url']
def javascript_url():
return FULLCALENDAR['javascript_url']
def jquery_url():
return FULLCALENDAR['jquery_url']
def jquery_ui_url():
return FULLCALENDAR['jquery_ui_url']
4. fullcalendar 템플릿 태그 작성
- 경로 : schedule > templatetags > fullcalendar_tags.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50from django import template
from django.utils.safestring import mark_safe
from ..fullcalendar import css_url, print_css_url, javascript_url, jquery_url, jquery_ui_url
register = template.Library()
def fullcalendar_css_url():
return css_url()
def fullcalendar_print_css_url():
return print_css_url()
def fullcalendar_javascript_url():
return javascript_url()
def fullcalendar_jquery_url():
return jquery_url()
def fullcalendar_jquery_ui_url():
return jquery_ui_url()
def fullcalendar_css():
url = fullcalendar_css_url()
return mark_safe("<link href='%s' rel='stylesheet'>" % url)
def fullcalendar_print_css():
url = fullcalendar_print_css_url()
return mark_safe("<link href='%s' rel='stylesheet' media='print'>" % url)
def fullcalendar_jquery():
url = fullcalendar_jquery_url()
return mark_safe("<script src='%s'></script>" % url)
def fullcalendar_jquery_ui():
url = fullcalendar_jquery_ui_url()
return mark_safe("<script src='%s'></script>" % url)
def fullcalendar_javascript():
url = fullcalendar_javascript_url()
return mark_safe("<script src='%s'></script>" % url)
5. fullcalendar를 표시할 html 파일 작성
경로 : config > layout > schedule-base.html
- 이곳에 fullcalendar_tags 탬플릿 태그 적용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<html class="no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% load fullcalendar_tags %}
{% fullcalendar_css %}
{% fullcalendar_print_css %}
{% fullcalendar_jquery %}
{% fullcalendar_jquery_ui %}
{% fullcalendar_javascript %}
{% calendar_init calendar_config_options %}
{% block extra_style %}
{% endblock %}
</head>
<body>
<!-- 주의 : 이 곳에 jquery script를 작성하면, fullcalendar가 작동되지 않는다. -->
{% block extra_script %}
{% endblock %}
</body>
</html>
- 이곳에 fullcalendar_tags 탬플릿 태그 적용
경로 : schedule(앱) > templates > schedule > index.html
- fullcalendar가 보여질 html 코드 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14{% extends "schedule-base.html" %}
{% load fullcalendar_tags %}
{% block content %}
<div>
...
<div style="height:800px; line-height:800px; width:800px; margin:0 auto;">
<div style="width:800px; display:inline-block; vertical-align:middle; line-height:normal;">
{% calendar %}
</div>
</div>
</div>
{% endblock %}
- fullcalendar가 보여질 html 코드 작성
6. util.py 작성
- 경로 : schedule > util.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67# coding: utf-8
import json
def date_handler(obj):
"""
Handles JSON serialization for datetime values
"""
return obj.isoformat() if hasattr(obj, 'isoformat') else obj
def convert_field_names(event_list):
"""
Converts atribute names from Python code convention to the
attribute names used by FullCalendar
"""
for event in event_list:
for key in event.keys():
event[snake_to_camel_case(key)] = event.pop(key)
return event_list
def snake_to_camel_case(s):
"""
Converts strings from 'snake_case' (Python code convention)
to CamelCase
"""
new_string = s
leading_count = 0
while new_string.find('_') == 0:
new_string = new_string[1:]
leading_count += 1
trailing_count = 0
while new_string.rfind('_') == len(new_string) - 1:
new_string = new_string[:-1]
trailing_count += 1
new_string = ''.join([word.title() for word in new_string.split('_')])
leading_underscores = '_' * leading_count
trailing_underscores = '_' * trailing_count
return leading_underscores + new_string[0].lower() + new_string[1:] + trailing_underscores
def events_to_json(events_queryset):
"""
Dumps a CalendarEvent queryset to the JSON expected by FullCalendar
"""
events_values = list(events_queryset.values('id', 'title', 'start', 'end', 'all_day'))
events_values = convert_field_names(events_values)
return json.dumps(events_values, default=date_handler)
def calendar_options(event_url, options):
"""
Builds the Fullcalendar options array
This function receives two strings. event_url is the url that returns a JSON array containing
the calendar events. options is a JSON string with all the other options.
"""
event_url_option = 'events: "%s"' % (event_url,)
s = options.strip()
if s is not None and '{' in s:
pos = s.index('{') + 1
else:
return '{%s}' % (event_url_option)
return s[:pos] + event_url_option + ', ' + s[pos:]
7. fullcalendar 모델 작성
- 경로 : schedule > models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21from django.db import models
from django.contrib.auth import get_user_model
from django.utils.translation import ugettext_lazy as _
class CalendarEvent(models.Model):
author = models.ForeignKey(get_user_model(), on_delete=models.SET_NULL, null=True, blank=True, related_name="schedules")
title = models.CharField(_('Title'), max_length=200)
start = models.DateTimeField(_('Start'))
end = models.DateTimeField(_('End'))
all_day = models.BooleanField(_('All day'), default=False)
# models.DateTimeField(input_formats=["%d %b %Y %H:%M:%S %Z"])
class Meta:
verbose_name = _('Event')
verbose_name_plural = _('Events')
ordering = ['-start']
# 관리자 사이트에 표시될 객체 이름 설정
def __str__(self):
return self.title
8. fullcalendar 뷰 작성
- 경로 : schedlue > views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40from django.shortcuts import render
from django.http import HttpResponse
from .models import CalendarEvent
from .util import events_to_json, calendar_options
OPTIONS = """{ timeFormat: "H:mm",
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay',
},
allDaySlot: false,
firstDay: 0,
weekMode: 'liquid',
slotMinutes: 15,
defaultEventMinutes: 30,
minTime: 8,
maxTime: 20,
editable: false,
dayClick: function(date, allDay, jsEvent, view) {
if (allDay) {
$('#calendar').fullCalendar('gotoDate', date)
$('#calendar').fullCalendar('changeView', 'agendaDay')
}
},
eventClick: function(event, jsEvent, view) {
if (view.name == 'month') {
$('#calendar').fullCalendar('gotoDate', event.start)
$('#calendar').fullCalendar('changeView', 'agendaDay')
}
},
}"""
def index(request):
event_url = 'all_events/'
return render(request, 'schedule/index.html', {'calendar_config_options': calendar_options(event_url, OPTIONS)})
def all_events(request):
events = CalendarEvent.objects.all()
return HttpResponse(events_to_json(events), content_type='application/json')
9. URL 설정
- 경로 : schedule > urls.py
1
2
3
4
5
6
7
8
9from django.urls import path
from .views import *
app_name = 'schedule'
urlpatterns = [
path('', index, name='index'),
path('all_events/', all_events, name='all_events'),
]
Posted
tags:
{ Django }
{ fullcalendar }