首页 > 解决方案 > DRF - django_filters - 使用自定义方法

问题描述

我有一个这样的模型:

class Agreement(models.Model):
    file_no = models.IntegerField(primary_key=True)
    contract_date = models.DateField()
    contract_time = models.IntegerField()

    @property
    def calculate_expiry_date(self):
        return self.contract_date + relativedelta(years=self.contract_time)

    @property
    def is_expired(self):
        return (self.contract_date + relativedelta(years=self.contract_time)) < timezone.now().date() 

is_expired 函数为每个协议返回 true 或 false

我有一个像这样的简单过滤器:

class AgreementFilter(filters.FilterSet):
    file_no = filters.NumberFilter(lookup_expr='icontains')

    class Meta:
        model = Agreement
        fields = ['file_no',] 

我认为我无法过滤属性字段,因为 Django 过滤器在数据库级别运行。那么,如果协议模型对象有效或无效或真或假,我怎样才能使其工作呢?

标签: djangopython-3.xdjango-rest-frameworkdjango-filters

解决方案


您可以向模型添加新字段,以Agreement保持协议的到期日期:

expiry_date = models.DateField()

如果contract_time字段是合同有效期的年数,并且您在添加新合同时知道它,那么您可以像现在一样计算到期日期并将其添加到expiry_date字段中,而无需属性装饰器。

现在您希望在添加新记录时自动完成,为此您可以使用 pre_save信号

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

@receiver(signals.pre_save, sender=WorkDone)
def calculate_expiry_date(sender, instance, **kwargs):
    instance.expiry_date = instances.contract_date + \
       relativedelta(years=instance.contract_time)

对于过滤部分,您可以使用当前日期来过滤记录。由于您使用的是 DRF,这将非常容易,在前端只需使用当前日期并将其作为过滤器参数传递,以显示仅显示日期大于当前日期的协议。


推荐阅读