2017-03-01 177 views
3

我有以下(簡化的)數據模型:Django的過濾對象

class Article(Model): 
    uuid = models.CharField(primary_key=True, max_length=128) 

class Attribute(Model): 
    uuid = models.CharField(primary_key=True, max_length=128) 
    article = models.ForeignKey(Article, related_name='attributes') 
    type = models.CharField(max_length=256) 
    value = models.CharField(max_length=256) 

一個示例用法是與連接到它與type="brand"value="Nike"一個屬性的製品。現在我想編寫一個可以獲得某品牌所有文章的API,但我似乎無法爲其編寫過濾器。這是我到目前爲止:

class PhotobookFilter(df.FilterSet): 
    brand = df.CharFilter(method='filter_brand') 

    class Meta: 
     model = Article 

    def filter_brand(self, queryset, name, value): 
     return queryset.filter('order__attributes') 

class PhotobookViewSet(AbstractOrderWriterViewSet): 
    queryset = Article.objects.all() 
    serializer_class = ArticlePhotobookSerializer 
    filter_backends = (filters.DjangoFilterBackend,) 
    filter_class = PhotobookFilter 

queryset.filter的行顯然不正確呢。我需要在這裏創建一個過濾器,返回包含屬性爲type="brand"value=value的所有文章。我將如何做到這一點?

回答

1

你確定要同時查找(typeAttributevalue)凝結成一個過濾器?爲什麼不允許單獨對兩個字段進行過濾?

E.g.

class PhotobookFilter(df.FilterSet): 
    type = df.CharFilter(method='filter_type') 
    value = df.CharFilter(method='filter_value') 

    class Meta: 
     model = Article 

    def filter_type(self, queryset, name, value): 
     return queryset.filter(**{'attributes__type': value}) 

    def filter_value(self, queryset, name, value): 
     return queryset.filter(**{'attributes__value': value}) 

而現在像?type=brand&value=Nike查詢應該工作。

很明顯,你可以凝結兩個條件成一個過濾器和例如硬編碼的帶狀部分:

class PhotobookFilter(df.FilterSet): 
    brand = df.CharFilter(method='filter_brand') 

    def filter_brand(self, queryset, name, value): 
     return queryset.filter(**{'attributes__type': 'brand', 'attributes__value': value}) 

但讓他們分開的感覺方式更加靈活。

+0

這不起作用,因爲'Article'上沒有字段叫'attribute'。它返回錯誤:'關係字段不支持嵌套查找。有一個名爲'attributes'的字段,我需要使用此類型 - 值組合過濾至少存在一個屬性的所有文章。 PS將兩者分開會更加困難,因爲我還需要在另一個類型 - 值組合上進行過濾,而在手頭,我需要的類型是預定義的。 – physicalattraction

+1

好的,我沒有在你的領域發現'related_name'。是的,如果你覺得這樣,你可以很難編碼過濾部分(見更新的例子)。如果不知道所有要求,很難猜測究竟有什麼意義。祝你好運。 – arie

0

使用search_fields。對於正確的結果重命名「類型」屬性名稱http://www.codesend.com/view/09ca65d42248fe1d89d07ce151f4f050/

+0

搜索領域是非常方便的,如果該字段' type'和'value'將在我查詢的模型中定義(在這種情況下爲'Article'),但在這種特殊情況下,這些字段沒有在'Article'中定義,而是在'Attribute'中定義,而I在模型「Article」中的字段'attributes'中有一個列表。 – physicalattraction

1

您還可以過濾相反這樣的:

class PhotobookFilter(df.FilterSet): 
    brand = df.CharFilter(method='filter_brand') 

    class Meta: 
     model = Article 

    def filter_brand(self, queryset, name, value): 
     articles = Attribute.objects.filter(type="brand", value=value).values_list('article_id', flat=True) 
     return queryset.filter(id__in=articles) 

這將創建一個子查詢Attribute,這將仍然是在最後一個SQL請求