Search code examples
djangodateforeign-keyshierarchy

How to get Django ForeignKey to behave like a DateField


I have a Day class whose ID is a DateField. I have an Event class that links via ForeignKey to that DateField. I'd like to use ModelAdmin features like date_hierarchy but I get

<class 'myapp.admin.EventAdmin'>: (admin.E128) 
The value of 'date_hierarchy' must be a DateField or DateTimeField.

This is my models.py file:

class Day(models.Model):
    date = models.DateField(primary_key=True)

    def __str__(self):
        return str(self.date)

class Event(models.Model):
    date = models.ForeignKey(Day, to_field='date', related_name='events')
    bullet = models.TextField()

    def __str__(self):
        return self.bullet[:20]

And admin.py has:

class EventAdmin(admin.ModelAdmin):
    list_display = ('date', 'bullet')
    search_fields = ('bullet',)
    list_filter = ('date',)
    date_hierarchy = 'date'
    ordering = ('-date',)

date_hierarchy doesn't work, and list_filter doesn't break things down by date.

Is there a way to convert the Event ForeignKey field to a form that's seen as a DateField?

I looked here and here unsuccessfully, although a feature coming in v1.11 may let me reference fields on related models directly.


Solution

  • I hope this is a contrived example because single column tables don't make much sense here. You can just as easily have this

    class Event(models.Model):
        date = models.DateField(primary_key=True)
        bullet = models.TextField()
    

    Assuming that you have left out some relevent fields and the Day model is important, event should just be:

    class Event(models.Model):
        date = models.ForeignKey(Day, related_name='events')
        bullet = models.TextField()
    

    The to_field isn't really usefull here. and then

    class EventAdmin(admin.ModelAdmin):
        list_display = ('date__date', 'bullet')
        search_fields = ('bullet',)
        list_filter = ('date__date',)
        date_hierarchy = 'date__date'
        ordering = ('-date__date',)