2017-02-08 119 views
0

我想把我的django-filter字段變成下拉菜單。django-filter下拉菜單

class UserFilter(django_filters.FilterSet): 
    class Meta: 
     model = Product 
     fields = ['category', 'genre', 'instrument', ] 


def filter(request): 
    filter = UserFilter(request.GET, queryset=Product.objects.all()) 
    return render(request, 'filter.html', {'filter': filter}) 

我試圖用ModelChoiceFilter,這樣來實現這一目標:

category=django_filters.ModelChoiceFilter(queryset=Product.objects.all()) 
genre = django_filters.ModelChoiceFilter(queryset=Product.objects.all()) 
instrument=django_filters.ModelChoiceFilter(queryset=Product.objects.all))) 

它的工作原理!然而,不是返回願望列,而是返回title提交給所有的Django表單字段。這是來自我的模型。

def __str__(self): 
    return self.title 

使用簡單的Django模型表單時可以觀察到相同的行爲。在這種情況下,我只是重寫ModelChoiceFieldlabel_from_instance功能是這樣的:

class CategoryModelChoiceField(ModelChoiceField): 
    def label_from_instance(self, obj): 
     return obj.category 

我的問題是如何覆蓋ModelChoiceFilter?或者可能有另一個方便的方法來實現Django過濾器的下拉菜單?

UPDATE

由於djnago過濾用的下拉列表中的默認ForeignKeys來了,我只是改變了我的模型。現在它看起來像這樣:

class Category(models.Model): 
    category = models.CharField(max_length=50, blank=True) 

class Genre(models.Model): 
    genre = models.CharField(max_length=50, blank=True) 


class Instrument(models.Model): 
    instrument = models.CharField(max_length=50, blank=True) 


class Product(models.Model): 
    category = models.ForeignKey(Category) 
    genre = models.ForeignKey(Genre) 
    instrument = models.ForeignKey(Instrument) 
    title = models.TextField(max_length=200, blank=True) 

    def __str__(self): 
     return self.title 

現在它改變了它的行爲。它忽略了對象的數量而不是實際的字符串。就像這樣:

Category object - Genre object - Instrument object - title1 
Category object - Genre object - Instrument object - title2 
Category object - Genre object - Instrument object - title3 

本身是沒有任何干預,做工精細的下拉菜單:

class UserFilter(django_filters.FilterSet): 
    class Meta: 
     model = Product 
     fields = ['category', 'genre', 'instrument', ] 

回答

1

我終於做到了工作。這是工作模式:

class Category(models.Model): 
    category = models.CharField(max_length=50, blank=True) 

    def __str__(self): 
     return self.category 


class Genre(models.Model): 
    genre = models.CharField(max_length=50, blank=True) 

    def __str__(self): 
     return self.genre 


class Instrument(models.Model): 
    instrument = models.CharField(max_length=50, blank=True) 

    def __str__(self): 
     return self.instrument 


class Product(models.Model): 
    category = models.ForeignKey(Category) 
    genre = models.ForeignKey(Genre) 
    instrument = models.ForeignKey(Instrument) 
    title = models.TextField(max_length=200, blank=True) 

    def __str__(self): 
     return self.title 
0

我已經使用了相同的解決方案,但有時完全標準化模型是我想避免的。也許我錯過了它,但我很驚訝django_filters.modelChoiceFilter不會簡單地返回查詢集中的任何屬性,而不僅僅是外鍵名稱。

下面是另一種從查詢集動態生成選項的解決方案。

class DynamicChoiceMixin(object): 

    @property 
    def field(self): 
     queryset = self.parent.queryset 
     field = super(DynamicChoiceMixin, self).field 

     choices = list() 
     have = list() 
     # iterate through the queryset and pull out the values for the field name 
     for item in queryset: 
      name = getattr(item, self.field_name) 
      if name in have: 
       continue 
      have.append(name) 
      choices.append((name, name)) 
     field.choices.choices = choices 
     return field 


class DynamicChoiceFilter(DynamicChoiceMixin, django_filters.ChoiceFilter): 
    pass 


class UserFilter(django_filters.FilterSet): 

    category = DynamicChoiceFilter(name=‘category’) 
    genre = DynamicChoiceFilter(name=‘genre’) 
    instrument = DynamicChoiceFilter(name=‘instrument’) 

    class Meta: 
     model = Product 
     fields = ['category', 'genre', 'instrument', ]