alias51
alias51

Reputation: 8638

Defined field in model not accessible

I have the following model

class Meeting(models.Model):
    meeting_title = models.CharField(default='', max_length=128, blank=True, null=True)
    meeting_time = models.TimeField(blank=False, null=False)
    meeting_date = models.DateField(blank=False, null=False)

    def meeting_datetime(self):
        return datetime.combine(self.meeting_date, self.meeting_time)

However, when I try to access the Meeting object via meeting_datetime I get Cannot resolve keyword 'meeting_datetime' into field. Choices are: id, meeting_title, meeting_time, meeting_date.

Why is meeting_datetime not an option? Doesn't the def create it as a DateTimeField? If not, how do I add it as a field, or otherwise access it?

Upvotes: 0

Views: 152

Answers (2)

Geo Jacob
Geo Jacob

Reputation: 6009

Either you can rewrite your model as:

class Meeting(models.Model):
   meeting_title = models.CharField(default='', max_length=128, blank=True, null=True)
   meeting_time = models.TimeField(blank=False, null=False)
   meeting_date = models.DateField(blank=False, null=False)
   meeting_datetime = models.DateTimeField(blank=True, null=False)

   def save(self, *args, **kwargs):
      self.meeting_datetime = datetime.combine(self.meeting_date, self.meeting_time)
      super(Meeting, self).save(*args, **kwargs)

or

you can filter your queryset as:

meeting_objs = Meeting.objects.filter(meeting_date__gt=datetime.date.today(),meeting_time__gt=datetime.datetime.now().time() )

Upvotes: 1

JoeLinux
JoeLinux

Reputation: 4307

That's because functions aren't represented as fields in Django. You have to call it as a function to get its value (m.meeting_datetime()). However, if you really want to access the value without it looking like a function call, you can use the property decorator:

class Meeting(models.Model):
    meeting_title = models.CharField(default='', max_length=128, blank=True, null=True)
    meeting_time = models.TimeField(blank=False, null=False)
    meeting_date = models.DateField(blank=False, null=False)

    @property
    def meeting_datetime(self):
        return datetime.combine(self.meeting_date, self.meeting_time)

That will allow you to access the meeting_datetime function as if it were a property:

>>> m = Meeting(...)
>>> m.meeting_datetime
# data

That being said, is there a good reason you separated a DateField and TimeField and didn't just use a single DateTimeField?

class Meeting(models.Model):
    meeting_title = models.CharField(default='', max_length=128, blank=True, null=True)
    meeting_datetime = models.DateTimeField()

Then you'd be able to access that field the same as you would above with the decorator example. Except that the value would be stored in your database, while the decorator example's value would be derived only when you access the property.

Upvotes: 2

Related Questions