Hi,
This might not be what you were looking for, but I’ll share how I tried approaching this problem in case it helps you.
For the model, I actually thought it would make sense to skip the date
field.
# concerts/models.py
from django.db import models
class Concert(models.Model):
name = models.CharField(max_length=100)
time_open_doors = models.DateTimeField(blank=True, null=True)
time_start = models.DateTimeField(null=True)
time_end = models.DateTimeField(blank=True, null=True)
This is how I specified the form
# concerts/forms.py
from concerts.models import Concert
from django import forms
from pytz import common_timezones
TZ_CHOICES = [(x, x) for x in common_timezones]
class ConcertForm(forms.Form):
name = forms.CharField(max_length=100, min_length=3, required=True, strip=True)
date = forms.DateField(label='Date on which doors open (or concert starts, if no doors open time is set)', required=True)
timezone = forms.ChoiceField(label='Timezone of concert locale', choices=TZ_CHOICES)
time_open_doors = forms.TimeField(label='Time when doors open', required=False)
time_start = forms.TimeField(label='Time when concert starts', required=True)
time_end = forms.TimeField(label='Time when concert ends', required=False)
If I understood you correctly, you actually wanted the user to be able to input a concert start time or a ‘doors open’ time. To make things work properly here you’d have to set both fields’s required
attribute to False and override the is_valid
method, I think, and add an additional check that either one is filled out)
As you can see, although the date never gets a field on its own in the database, the user is asked to input the date separately from the involved times. I also specified that it’s the date when the earliest time occurs, since it’s possible that the concert goes on through the night. I’m assuming though that no concerts will go on for >24 hours, which might be unrealistic for some really hardcore bands.
I’m including a time zone choice, as this is important unless the site only handles very local concerts and it’s safe to assume that all concert-holders and -goers will be in the same time zone.
For views I did this:
# concerts/views.py
from django.urls import reverse_lazy
from django.views.generic import FormView, ListView
from datetime import datetime, timedelta
import pytz
from .forms import ConcertForm
from .models import Concert
day_delta = timedelta(days=1)
class ConcertFormView(FormView):
form_class = ConcertForm
template_name = 'concerts/concert-create.html'
success_url = reverse_lazy('home')
def form_valid(self, form):
name = form.cleaned_data.get('name')
timezone = form.cleaned_data.get('timezone')
date = form.cleaned_data.get('date')
time_open_doors =form.cleaned_data.get('time_open_doors')
if time_open_doors:
datetime_open_doors = datetime.combine(date, time_open_doors)
datetime_open_doors = pytz.timezone(timezone).localize(datetime_open_doors)
time_start =form.cleaned_data.get('time_start')
datetime_start = datetime.combine(date, time_start)
if time_open_doors and time_start < time_open_doors:
datetime_start = datetime_start + day_delta
datetime_start = pytz.timezone(timezone).localize(datetime_start)
time_end =form.cleaned_data.get('time_end')
datetime_end = datetime.combine(date, time_end)
if datetime_end and (time_open_doors and time_end < time_open_doors) or\
(time_open_doors and time_open_doors < time_start):
datetime_end = datetime_end + day_delta
datetime_end = pytz.timezone(timezone).localize(datetime_end)
print(datetime_start)
save_data = {'name': name, 'time_start': datetime_start,
'time_end': datetime_end}
if time_open_doors:
save_data['time_open_doors'] = datetime_open_doors
c = Concert(**save_data)
c.save()
return super().form_valid(form)
class ConcertListView(ListView):
model = Concert
template_name = 'concerts/home.html'
context_object_name = 'concerts'
So I override the form_valid
method of the FormView, and make sure that if the user has input e. g . times “22:00”, “23:00”, “03:00”, then the date for the final datetime is shifted forward by one day. The specified timezone is also added. There ought to be cleaner solutions, but maybe it helps you get going. Note that you will want to think about how timezones should be handled on your site. Do you want the concert times to always be displayed in the time zone of the area where the concert is held? Or do you want them to be displayed (e. g. if there are live streams/online concerts) in the concert-goers time zone?
Hope this helps