Django Admin按函数/过滤器仅按反向外键查找中的第一个对象进行过滤

时间:2016-05-10 00:42:55

标签: python django filter

我正在尝试在django中按功能构建过滤器。从我通过谷歌搜索学到的东西来看,这很难实现。

所以这是我的代码:

class TrackingEventType(models.Model):
    name = models.CharField(blank=False, null=False, max_length=255)

class TrackingEvent(models.Model):    
    datetime = models.DateTimeField(blank=False, null=False, default=datetime.now, verbose_name="Zeitpunkt")    
    event_type = models.ForeignKey(TrackingEventType, help_text="Art des Events")    
    tracking = models.ForeignKey('Tracking')    

    class Meta:
        ordering = ['-datetime']


class Tracking(models.Model):
    tracking_no = models.CharField(blank=False, null=False, max_length=10, unique=True, verbose_name="Tracking Nummer")

    def get_last_event(self):
        """
        Todo: return the latest event.
        """
        return TrackingEvent.objects.filter(tracking=self.id).first()
    get_last_event.short_description = 'Last event'

    class Meta:
        ordering = ['-tracking_no']

我的目标是可以按最后一个事件类型名称过滤跟踪对象。在django admin中显示功能的结果很简单,但添加相应的过滤器不是。

我的想法也是尝试构建类似的过滤器:

trackingevent__set__first__event_type__name

但是,那太容易了。)

欢迎任何意见。

1 个答案:

答案 0 :(得分:1)

正如您所发现的那样以这种方式进行过滤并非易事。如果您定期访问该信息,它可能也不是很有效。

我建议您在Tracking模型中存储对最新跟踪事件的引用:

class Tracking(models.Model)
    # ...
    last_event = models.ForeignKey(TrackingEvent, null=True)

每当创建新的跟踪事件时,您都会使用signals更新此引用。有点像:

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=TrackingEvent)
def update_latest_tracking_event(sender, instance, created, **kwargs):
    # Is this a new event?
    if created:
        # If yes, then update the Tracking reference
        tracking = instance.tracking
        tracking.last_event = instance
        tracking.save()

(请阅读有关此代码放置位置的文档。)

一旦完成所有这些操作,就可以根据最后一个跟踪事件类型进行过滤:

# I'm just guess what event types you have...
cancellation = TrackingEventType.objects.get(name='cancel')
Tracking.objects.filter(last_event__event_type=cancellation)