2014-06-25 13 views
8

REST API - see django docs on this adresindeki sorgu paramlarına karşı filtre uygulamak istiyorum. Ancak, ben göre filtreleme isteyen bir parametresi bir modeli @ özellik aracılığıyla kullanılabilirDjango-rest-framework ile filtrede özel yöntemler kullanma

örnek models.py: Burada

class Listing(models.Model): 
    product = models.OneToOneField(Product, related_name='listing') 
    ... 
    @property 
    def category(self): 
     return self.product.assets[0].category.name 

django-filter docs

class ListingFilter(django_filters.FilterSet): 
     product = django_filters.CharFilter(name='product__name') 
     category = django_filters.CharFilter(name='category') #DOES NOT WORK!! 

     class Meta: 
      model = Listing 
      fields = ['product','category'] 

    class ListingList(generics.ListCreateAPIView): 
     queryset = Listing.objects.all() 
     serializer_class = ListingSerializer 
     filter_class = ListingFilter 
uyarınca benim İlanı API için hazırlandığında

Nasıl listing.category tarafından uygun şekilde filtreleyebilirim? Liste modelinde doğrudan mevcut değildir.

def filter_category(queryset, value): 
     if not value: 
      return queryset 

     queryset = ...custom filtering on queryset using 'value'... 
     return queryset 

Liste filtresi gibi görünmelidir: kategori parametresinin değerini kullanarak bir Sorgu Kümesi filtreleyen bir yöntem tanımlayan see django-filter docs

İlk -

+0

, başka bir soru bu cevap olabilir yardım: http://stackoverflow.com/questions/14258338/django-rest-framework-filtering/35506369#35506369 – iankit

cevap

13

özel yöntemini belirtmek için 'eylem' parametresini kullanın :

class ListingFilter(django_filters.FilterSet): 
     ... 
     category = django_filters.CharFilter(action=filter_category) 
     ... 
+4

Sadece django-filter 'eyleminin' method' ile değiştirildiğini gösteren kısa bir not. http://django-filter.readthedocs.io/en/latest/migration.html –

-1

veritabanı hız uğruna, sadece listeleme modeline kategoriyi eklemek gerekir

class Listing(models.Model): 
    product = models.OneToOneField(Product, related_name='listing') 
    category = models.ForeignKey(Category) 

Sonra Sonra adının göre filtreleme alan

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

@receiver(post_save, sender=Product) 
def updateCategory(sender, instance, created, update_fields, **kwargs): 
    product = instance 
    product.listing.category = product.assets[0].category.name 
    product.listing.save() 

haberdar olmasını sağlamanın post_save signal kullanmak başka herhangi bir alan olarak: Bu tür durumlar için

class ListingFilter(django_filters.FilterSet): 
    ... 
    category = django_filters.CharFilter(name='category__name') 
    ...