Reputation: 131
I am very new to Django and programming in general and I am facing a challenge I have not seen before. I a looking for a bit of help with DateTimeField().
As a learning project, I am setting up a simple travel app. I would like users to be able to add trips, descriptions, etc. So far, so good.
I would like to add two DateTimeFields to my trips model. The start_date entered must be a date in the future (from the time they are using the app), while the end_date will have to be after the start_date (natch). How do I program this into my models?
Here is my current code for my Trip class:
class Trip(models.Model):
destination = models.CharField(max_length=55)
description = models.TextField()
start_date = models.DateTimeField(??)
end_date = models.DateTimeField(??)
travellers = models.ManyToManyField(User, related_name="trips")
planned_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name="trips_added")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Thank you.
Update
Thanks to you guys I am getting closer. However, I think there is a wrinkle or two in DateField (I don't actually need DateTimeField) that I am missing. Here is my Trip table in models:
class Trip(models.Model):
destination = models.CharField(max_length=55)
description = models.TextField()
start_date = models.DateField(null=True)
end_date = models.DateField(null=True)
travelers = models.ManyToManyField(User, related_name="trips")
planned_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name="trips_added")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = TripManager()
Also in models, under my TripManager, I have the following validation method:
def trip_validation(self, postData):
errors = {}
if len(postData['destination']) < 1:
errors['destination'] = 'You must enter trip destination.'
if len(postData['description']) < 1:
errors['description'] = 'You must enter trip description.'
if len(postData['start_date']) < 1:
errors['start_date'] = 'Please enter a start date for your trip.'
elif not postData['start_date'] > timezone.now():
errors['start_date'] = 'Your trip start date must be in the future.'
if len(postData['end_date']) < 1:
errors['end_date'] = 'Please enter an end date for your trip.'
elif not self.end_date > self.start_date:
errors['end_date'] = 'Trip end date must be after start date.'
return errors
In views, I call the trip_validation method and sent the errors to the template via a context dict.
All of the validation methods work save elif not postData['start_date'] > timezone.now():
and elif not self.end_date > self.start_date:
.
I get the following error: TypeError at /trips/add/
can't compare datetime.datetime to unicode
.
This leads me to believe that I am not using the built-in DateField function properly somewhere along the line.
Thank you.
Upvotes: 2
Views: 3651
Reputation: 1731
You need to convert into the right data type before comparing. You can use datetime.strptime() as shown below.
from datetime import datetime
s_date = datetime.strptime(postData['start_date'], "%Y-%m-%d")
e_date = datetime.strptime(postData['end_date'], "%Y-%m-%d")
Upvotes: 0
Reputation: 88449
I prefer to set those fields to blank=True
and null=True
and do some Validation checks by overriding the save()
method of the Trip
model, as
from django.utils import timezone
from django.core.exceptions import ValidationError
class Trip(models.Model):
# your fields
start_date = models.DateTimeField(blank=True, null=True)
end_date = models.DateTimeField(blank=True, null=True)
# your fields
def save(self, *args, **kwargs):
if self.start_date:
if not self.start_date > timezone.now():
raise ValidationError("start_time must be greater than current time")
if self.end_date:
if not self.start_date:
raise ValidationError("start time missing. Please check the data")
if not self.end_date > self.start_date:
raise ValidationError("end time must be greater than start time")
super().save(*args, **kwargs)
Upvotes: 1
Reputation: 198
You don't do that in the model. The model is simply a table in a database, so there you just define that the fields start_date and end_date are of the type DateTimeField. You can find more info here: Django Models
What you are trying to accomplish you ca do it in other part of Django, like in the view. There, when you get the dates inserted by the user, you can validate that start_date is in the future and end_date is after.
Upvotes: 0