2017-07-08 3 views
3

Sorry für eine neue Frage. Ich habe ein folgendes Modell:Django Rest Framework Filterung berechnet Modelleigenschaft

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() 

Serializer:

class WeightSlipSerializer(serializers.ModelSerializer): 

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

Ich versuche, die django-rest-framework-filters zu filtern auf der berechneten 'Netweight' und 'slipdate' Eigenschaften zu verwenden:

class WeightSlipFilter(FilterSet): 

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

Dies gibt mir einen Fehler:

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

Gibt es eine Problemumgehung für dieses Problem außer dem Hinzufügen der berechneten Felder zu der Datenbank?

Vielen Dank im Voraus.

Antwort

4

Sie können einen benutzerdefinierten Filter für slipdate, netweight erstellen, der diese Felder in db auswertet und filtert. Hierfür können Sie conditional expressions und F 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

Vielen Dank, große Hilfe verwenden, da die meisten meiner Projekt auf berechnete Felder enthält Filterung. –