Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Meta.fields contains a field that isn't defined on this FilterSet: ****

I am using Django Filters package .

I define my filter in following way in the view

class UnitFilter(django_filters.FilterSet):
    class Meta:
        model = Unit
        fields = [
            'floor', 'number', 'building','lease','leaseterm', 
            'lease__is_active','lease__is_terminated','lease__is_renewed',]

My Unit Model on which I filter is following

class Unit(CommonInfo):
    version = IntegerVersionField( )
    number = models.CharField(max_length=30,null=True, blank=True)
    max_occupants = models.PositiveSmallIntegerField()
    floor = models.PositiveSmallIntegerField()
    rooms = models.PositiveSmallIntegerField()
    is_disabled_access = models.BooleanField(default=False)
    balcony_quantity = models.PositiveSmallIntegerField()
    building = models.ForeignKey(Building)
    recomended_price = models.DecimalField(max_digits=7, decimal_places=2)
    _lease = None
    _leaseterm = None
    #check = models.ManyToManyField(UnitCheck, through='UnitChecklist')

    def _get_total(self):

        from conditions.models import LeaseTerm
        from lease.models import Lease

        lease_dict = Lease.objects.filter(unit_id=self.id, is_active = True , is_terminated = False).aggregate(Max('id'))
        if lease_dict['id__max']:
            lease =  lease_dict['id__max'] 
        else:  
            lease =  0

        leaseterm_dict = LeaseTerm.objects.filter(lease_id=lease, is_active = True , is_terminated = False).aggregate(Max('id'))
        if leaseterm_dict['id__max']:
            leaseterm =  leaseterm_dict['id__max'] 
        else:  
            leaseterm =  0

        self._lease = lease
        self._leaseterm = leaseterm

    @property
    def lease(self):
        if self._lease is None:
            self._get_total()
        return self._lease

    @property
    def leaseterm(self):
        if self._leaseterm is None:
            self._get_total()
        return self._leaseterm

There is 2 calculated properties in this model lease and leaseterm

lease property has no problem when leaseterm gives me this error

Meta.fields contains a field that isn't defined on this FilterSet: leaseterm

why? it it a bug in django-filter?Any work around?

like image 681
Ilya Bibik Avatar asked Oct 16 '16 14:10

Ilya Bibik


People also ask

What is FilterSet in Django?

The FilterSet is capable of automatically generating filters for a given model 's fields. Similar to Django's ModelForm , filters are created based on the underlying model field's type.

What is meta in Django serializer?

For what purpose is the class Meta: used in the class inside the Django serializers.py file? it tells it the model to use and what fields to serialize ... It serves the same point as using a Meta class object inside a Django model class, or a form class, etc.

What is the use of meta in Django?

Model Meta is basically the inner class of your model class. Model Meta is basically used to change the behavior of your model fields like changing order options,verbose_name, and a lot of other options. It's completely optional to add a Meta class to your model.

What does class meta mean?

In object-oriented programming, a metaclass is a class whose instances are classes. Just as an ordinary class defines the behavior of certain objects, a metaclass defines the behavior of certain classes and their instances. Not all object-oriented programming languages support metaclasses.


1 Answers

See this for a good explanation.

When you do queryset.filter(field_name=field_value), Django translates that into a SQL query. Unfortunately, calculated properties only live on the Python object, so you can't filter by them.

The workaround is to, whenever you filter by one of these, include an annotation to your queryset that adds the proper field in SQL. The link has a good example of how to do this. It's harder than doing it in Python, but the only way to go really.

like image 105
Sam Bobel Avatar answered Oct 22 '22 19:10

Sam Bobel