2014-06-25 21 views
8

Tôi muốn lọc các tham số truy vấn trong API REST của mình - see django docs on this. Tuy nhiên, một thông số tôi muốn lọc theo chỉ có sẵn thông qua một mô hình @propertySử dụng các phương pháp tùy chỉnh trong bộ lọc bằng django-rest-framework

dụ models.py:

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

Đây là thiết lập cho API Liệt kê của tôi phù hợp với 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 

Làm cách nào để lọc danh sách listing.category một cách thích hợp? Nó không có sẵn trên mô hình danh sách trực tiếp.

+0

Đối với trường hợp này, câu trả lời này của câu hỏi khác có thể trợ giúp: http://stackoverflow.com/questions/14258338/django-rest-framework-filtering/35506369#35506369 – iankit

Trả lời

13

Sử dụng các tham số 'hành động' để xác định một phương pháp tùy chỉnh - see django-filter docs

Đầu tiên xác định một phương pháp mà các bộ lọc một queryset sử dụng giá trị của tham số thể loại:

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

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

lọc Liệt kê sẽ trông như thế này :

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

Chỉ cần lưu ý nhanh rằng bộ lọc "hành động" django đã được thay thế bằng 'phương thức'. http://django-filter.readthedocs.io/en/latest/migration.html –

-1

Vì lợi ích của tốc độ cơ sở dữ liệu, bạn chỉ cần thêm danh mục vào mô hình danh sách

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

Sau đó sử dụng một post_save signal để giữ hiện trường được cập nhật

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

Sau đó lọc theo tên của nó như bạn làm bất kỳ lĩnh vực khác:

class ListingFilter(django_filters.FilterSet): 
    ... 
    category = django_filters.CharFilter(name='category__name') 
    ... 
Các vấn đề liên quan