Add prev, next month and new, edit event functionality

This commit is contained in:
Hui Wen 2018-07-30 23:07:14 -07:00
parent c3eb1b27d4
commit 45eab3154b
14 changed files with 172 additions and 21 deletions

2
.gitignore vendored
View file

@ -1,3 +1,5 @@
db.sqlite3
.vscode/
env/
static/
*.pyc

18
cal/forms.py Normal file
View file

@ -0,0 +1,18 @@
from django.forms import ModelForm, DateInput
from cal.models import Event
class EventForm(ModelForm):
class Meta:
model = Event
# datetime-local is a HTML5 input type, format to make date time show on fields
widgets = {
'start_time': DateInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%dT%H:%M'),
'end_time': DateInput(attrs={'type': 'datetime-local'}, format='%Y-%m-%dT%H:%M'),
}
fields = '__all__'
def __init__(self, *args, **kwargs):
super(EventForm, self).__init__(*args, **kwargs)
# input_formats parses HTML5 datetime-local input to datetime field
self.fields['start_time'].input_formats = ('%Y-%m-%dT%H:%M',)
self.fields['end_time'].input_formats = ('%Y-%m-%dT%H:%M',)

View file

@ -1,10 +1,13 @@
from django.db import models
# Create your models here.
from django.urls import reverse
class Event(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
start_time = models.DateTimeField()
end_time = models.DateTimeField()
@property
def get_html_url(self):
url = reverse('cal:event_edit', args=(self.id,))
return f'<a href="{url}"> {self.title} </a>'

View file

@ -1,28 +1,73 @@
.calendar {
/* Common styles */
body {
font-family: "ptsans", "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.left {
float: left;
}
.right {
float: right;
}
.btn {
outline: none;
color: black;
background-color: transparent;
box-shadow: 0 0 0 0;
margin-right: 3px;
}
.clearfix {
margin: 15px;
}
.form {
margin: auto;
}
.form input, .form select, .form textarea {
border-radius: 5px;
border: 1px solid #17a2b8;
outline: none;
background: none;
padding: 5px;
width: 100%;
}
/* App styles */
.title {
text-align: center;
margin: 10px;
}
.calendar {
width: 98%;
margin: auto;
font-size: 13px;
}
.month {
font-size: 25px;
}
tr, td {
.calendar tr, .calendar td {
border: 1px solid black;
}
th {
.calendar th {
padding: 10px;
text-align: center;
font-size: 18px;
}
td {
.calendar td {
width: 200px;
height: 150px;
padding: 20px 0px 0px 5px;
}
.month {
font-size: 25px;
}
.date {
font-size: 16px;
}

View file

@ -16,6 +16,9 @@
</head>
<body>
<h1 class="title">{% block title %}{% endblock %}</h1>
<hr>
{% block content %}
{% endblock %}

View file

@ -1,5 +1,15 @@
{% extends 'cal/base.html' %}
{% block title %}
Calendar
{% endblock %}
{% block content %}
<div class="clearfix">
<a class="btn btn-info left" href="{% url 'cal:calendar' %}?{{ prev_month }}"> Previous Month </a>
<a class="btn btn-info right" href="{% url 'cal:calendar' %}?{{ next_month }}"> Next Month </a>
<a class="btn btn-info right" href="{% url 'cal:event_new' %}"> New Event </a>
</div>
{{ calendar }}
{% endblock %}

View file

@ -0,0 +1,34 @@
{% extends 'cal/base.html' %}
{% block title %}
Event
{% endblock %}
{% block content %}
<div class="clearfix">
<a class="btn btn-info left" href="{% url 'cal:calendar' %}"> Calendar </a>
</div>
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
{{ field.label }} <strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
{{ field.label }} <strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
<form method="post">
{% csrf_token %}
<table class="form form-table">
{{ form }}
<tr><td colspan="2"><button type="submit" class="btn btn-info right"> Submit </button></td></tr>
</table>
</form>
{% endblock %}

View file

@ -5,4 +5,6 @@ app_name = 'cal'
urlpatterns = [
url(r'^index/$', views.index, name='index'),
url(r'^calendar/$', views.CalendarView.as_view(), name='calendar'),
url(r'^event/new/$', views.event, name='event_new'),
url(r'^event/edit/(?P<event_id>\d+)/$', views.event, name='event_edit'),
]

View file

@ -14,7 +14,7 @@ class Calendar(HTMLCalendar):
events_per_day = events.filter(start_time__day=day)
d = ''
for event in events_per_day:
d += f'<li> {event.title} </li>'
d += f'<li> {event.get_html_url} </li>'
if day != 0:
return f"<td><span class='date'>{day}</span><ul> {d} </ul></td>"

View file

@ -1,11 +1,14 @@
from datetime import datetime
from django.shortcuts import render
from django.http import HttpResponse
from datetime import datetime, timedelta, date
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.views import generic
from django.urls import reverse
from django.utils.safestring import mark_safe
import calendar
from .models import *
from .utils import Calendar
from .forms import EventForm
def index(request):
return HttpResponse('hello')
@ -16,14 +19,42 @@ class CalendarView(generic.ListView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
d = get_date(self.request.GET.get('day', None))
d = get_date(self.request.GET.get('month', None))
cal = Calendar(d.year, d.month)
html_cal = cal.formatmonth(withyear=True)
context['calendar'] = mark_safe(html_cal)
context['prev_month'] = prev_month(d)
context['next_month'] = next_month(d)
return context
def get_date(req_day):
if req_day:
year, month = (int(x) for x in req_day.split('-'))
def get_date(req_month):
if req_month:
year, month = (int(x) for x in req_month.split('-'))
return date(year, month, day=1)
return datetime.today()
return datetime.today()
def prev_month(d):
first = d.replace(day=1)
prev_month = first - timedelta(days=1)
month = 'month=' + str(prev_month.year) + '-' + str(prev_month.month)
return month
def next_month(d):
days_in_month = calendar.monthrange(d.year, d.month)[1]
last = d.replace(day=days_in_month)
next_month = last + timedelta(days=1)
month = 'month=' + str(next_month.year) + '-' + str(next_month.month)
return month
def event(request, event_id=None):
instance = Event()
if event_id:
instance = get_object_or_404(Event, pk=event_id)
else:
instance = Event()
form = EventForm(request.POST or None, instance=instance)
if request.POST and form.is_valid():
form.save()
return HttpResponseRedirect(reverse('cal:calendar'))
return render(request, 'cal/event.html', {'form': form})

View file

@ -118,4 +118,7 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_URL = '/static/'
# Physical system path where the static files are stored.
STATIC_ROOT = os.path.join(BASE_DIR, 'static').replace('\\', '/')
# URL that your STATIC files will be accessible through the browser.
STATIC_URL = '/static/'

BIN
images/calendar_v2.0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB