I have a model that looks like:
class MySchedule(models.Model):
start_datetime=models.DateTimeField()
name=models.CharField('Name',max_length=75)
With it comes its ModelForm:
class MyScheduleForm(forms.ModelForm):
startdate=forms.DateField()
starthour=forms.ChoiceField(choices=((6,"6am"),(7,"7am"),(8,"8am"),(9,"9am"),(10,"10am"),(11,"11am"),
(12,"noon"),(13,"1pm"),(14,"2pm"),(15,"3pm"),(16,"4pm"),(17,"5pm"),
(18,"6pm"
startminute=forms.ChoiceField(choices=((0,":00"),(15,":15"),(30,":30"),(45,":45")))),(19,"7pm"),(20,"8pm"),(21,"9pm"),(22,"10pm"),(23,"11pm")))
class Meta:
model=MySchedule
def clean(self):
starttime=time(int(self.cleaned_data.get('starthour')),int(self.cleaned_data.get('startminute')))
return self.cleaned_data
try:
self.instance.start_datetime=datetime.combine(self.cleaned_data.get("startdate"),starttime)
except TypeError:
raise forms.ValidationError("There's a problem with your start or end date")
Basically, I'm trying to break the DateTime field in the model into 3 more easily usable form fields -- a date picker, an hour dropdown, and a minute dropdown. Then, once I've gotten the three inputs, I reassemble them into a DateTime and save it to the model.
A few questions:
1) Is this totally the wrong way to go about doing it? I don't want to create fields in the model for hours, minutes, etc, since that's all basically just intermediary data, so I'd like a way to break the DateTime field into sub-fields.
2) The difficulty I'm running into is when the startdate field is blank -- it seems like it never gets checked for non-blankness, and just ends up throwing up a TypeError later when the program expects a date and gets None. Where does Django check for blank inputs, and raise the error that eventually goes back to the form? Is this my responsibility? If so, how do I do it, since it doesn't evaluate clean_startdate() since startdate isn't in the model.
3) Is there some better way to do this with inheritance? Perhaps inherit the MyScheduleForm in BetterScheduleForm and add the fields there? How would I do this? (I've been playing around with it for over an hours and can't seem to get it)
Thanks!
[Edit:] Left off the return self.cleaned_data -- lost it in the copy/paste originally
Set the exclude attribute of the ModelForm 's inner Meta class to a list of fields to be excluded from the form.
If I were you, I would have used the customised Django-admin date/time widget(s) for entering date/time entries.
Regarding form validation, make sure you pass the form associated with the request for it to show up form-based errors. (Sample code below)
As for using inheritance, it would be a overkill for this use-case as it will not serve any purpose and it would be better to keep things simple.
Sample code:
if request.POST:
form = MyScheduleForm(request.POST)
if form.is_valid():
# Specific stuff with the variables here
pass
else:
form = MyScheduleForm()
Ok, I think I figured it out:
As of Django 1.2, running is_valid() triggers MODEL validation on ModelForms. I had assumed that fields would be checked for blank values BEFORE hitting the model clean() function, so my clean function doesn't check for blank values or None types. Basically, my clean() in my model looks something like:
def clean(self):
if self.start_datetime > datetime.now():
raise ValidationError('Start date can\'t be in the future')
So I suppose that mostly answer my question. However, I have 1 remaining question:
Is it best to check for blank values in the model clean(), or is there a better way to do this? Seems hackish to check for blanks in the model instead of in the ModelForm -- is the validation on the form field supposed to flag missing inputs on required fields?
Thanks for everyone's help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With