2017-07-08 6 views
3

初心者の質問に申し訳ありません。私は、次のモデルがあります:私は、計算された 'netweight' と 'slipdateのプロパティに基づいてフィルタリングするdjango-rest-framework-filtersを使用しようとしていますDjango Rest Frameworkフィルタリング計算モデルプロパティ

class WeightSlipSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = models.WeightSlip 
     fields = ('grossdate', 'grossweight', 'taredate', 'tareweight', 'slipdate', 'netweight', 'vehicle') 
     read_only_fields = ('slipdate', 'netweight') 

class WeightSlip(models.Model): 

    grossdate = models.DateTimeField(auto_now=False, auto_now_add=False) 
    grossweight = models.DecimalField(max_digits=6, decimal_places=2, default=0) 
    taredate = models.DateTimeField(auto_now=False, auto_now_add=False) 
    tareweight = models.DecimalField(max_digits=6, decimal_places=2, default=0) 
    vehicle = models.CharField(max_length=12) 

    @property 
    def netweight(self): 
     return self.grossweight - self.tareweight 

    @property 
    def slipdate(self): 
     if self.grossdate > self.taredate: 
      return grossdate.date() 
     else: 
      return taredate.date() 

シリアライザを

class WeightSlipFilter(FilterSet): 

    class Meta: 
     model = WeightSlip 
     fields = ('slipdate', 'netweight', 'vehicle') 

これは私にエラーを与える:

TypeError: 'Meta.fields' contains fields that are not defined on this FilterSet: slipdate, netweight 

計算されたフィールドをデータベースに追加する以外に、この問題の回避策がありますか?

ありがとうございます。

答えて

4

slipdate, netweightのカスタムフィルタを作成して、このフィールドを評価してフィルタリングすることができます。このためにはconditional expressionsF expression

from django.db.models import F, Case, When 

class WeightSlipFilter(FilterSet): 
    slipdate = DateTimeFilter(method='filter_slipdate') 
    netweight = NumberFilter(method='filter_netweight') 

    class Meta: 
     model = WeightSlip 
     fields = ('slipdate', 'netweight', 'vehicle') 

    def filter_netweight(self, queryset, value): 
     if value: 
      queryset = queryset.annotate(netweight=F('grossweight') - F('tareweight')).filter(netweight=value) 
     return queryset 

    def filter_slipdate(self, queryset, value): 
     if value: 
      queryset = queryset.annotate(slipdate=Case(When(grossdate__gt=F('taredate'), then=F('grossdate')), default=F('taredate')).filter(slipdate=value) 
     return queryset 
+0

どうもありがとう、私のプロジェクトのほとんどは計算フィールド上でフィルタリングが含まれていますので、大きな助けを使用することができます。 –

関連する問題