开发者

Django filters - Using an AllValuesFilter (with a LinkWidget) on a ManyToManyField

This is my first Stack Overflow question, so please let me know if I do anything wrong.

I wish to create an AllValues filter on a ManyToMany field using the wonderful django-filters application. Basically, I want to create a filter that looks like it does in the Admin, so I also want to use the LinkWidget too.

Unfortunately, I get an error (Invalid field name: 'operator') if I try this the standard way:

# Models
class Organisation(models.Model):
    name = models.CharField()  
    ...  

class Sign(models.Model):  
    name = models.CharField()  
    operator = models.ManyToManyField('Organisation', blank=True)  
    ...  

# Filter
class SignFilter(LinkOrderFilterSet):  
    operator = django_filters.AllValuesFilter(widget=django_filters.widgets.LinkWidget)  

    class Meta:
        model = Sign
        fields = ['operator']

I got around this by creating my own filter with the many to many relationship hard coded:

# Models
class Organisation(models.Model):
    name = models.CharField()  
    ...  

class Sign(models.Model):  
    name = models.CharField()  
    operator = models.ManyToManyField('Organisation', blank=True)  
    ...  

# Filter
class MyFilter(django_filters.ChoiceFilter):  
    @property  
    def field(self):  
        cd = {}  
        for row in self.model.objects.all():  
            orgs = row.operator.select_related().values()  
        for org in orgs:  
            cd[org['id']] = org['name']    
        choices = zip(cd.keys(), cd.values())  
        list.sort(choices, key=lambd开发者_如何学编程a x:(x[1], x[0]))  
        self.extra['choices'] = choices  
        return super(AllValuesFilter, self).field  

class SignFilter(LinkOrderFilterSet):  
    operator = MyFilter(widget=django_filters.widgets.LinkWidget)  

I am new to Python and Django. Can someone think of a more generic/elegant way of doing this?


Why did you subclass LinkOrderFilterSet?

Maybe the connect way to use it is this:

import django_filters 

class SignFilter(django_filters.FilterSet):  
    operator = django_filters.AllValuesFilter(widget=django_filters.widgets.LinkWidget)  

    class Meta:
        model = Sign
        fields = ['operator']


You can use this

class CircleFilter(django_filters.FilterSet):
    l = []
    for c in Organisation.objects.all():
        l.append((c.id, c.name))
    operator = django_filters.ChoiceFilter(
        choices=set(l))

class Meta:
    model = Sign
    fields = ['operator']
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜