使用django-filter

时间:2019-11-18 15:14:48

标签: django django-2.0 django-filters

我有两个模型“用户”和“属性”,每个用户都有多个属性

class User(models.Model):
    userid =  models.CharField(max_length=200, primary_key=True)
    name =   models.CharField(max_length=200)
    email =   models.CharField(max_length=200)
    def __str__(self):
       return self.userid

class Attribute(models.Model):
    userid = models.ForeignKey(User,on_delete=models.CASCADE)
    rolechoice = (('admin','admin'),('visitor','visitor'),('customer','customer'),('user','user'))
    type =   models.CharField(max_length=15,choices = rolechoice)
    value =   models.CharField(max_length=200)
    def __str__(self):
        return str(self.value)

我可以在用户页面中按名称,ID,电子邮件进行过滤,但可以按我不知道的Attribute类中存在的角色进行过滤。

这是我的观点:

def users_search(request):
    user_list = User.objects.all()
    user_filter = UserFilter(request.GET, queryset=user_list)
    return render(request, 'myapp/users_list.html', {'filter': user_filter})

这是我的filter.py

class UserFilter(django_filters.FilterSet):
    userid = django_filters.CharFilter(lookup_expr='icontains')
    name = django_filters.CharFilter(lookup_expr='icontains')
    email = django_filters.CharFilter(lookup_expr='icontains')
    attributes = django_filters.ModelChoiceFilter(queryset=Attribute.objects.all())
    class Meta:
        model = User
        fields = ['userid','name','email','attributes']

感谢您的帮助:)

新更新:

更改型号

class Attribute(models.Model):
    userid = models.ForeignKey(User,related_name='users', on_delete=models.CASCADE)

在过滤器中:

attributes = django_filters.ChoiceFilter( field_name='userid__type', choices=Attribute.rolechoice, label = 'Role' )

结束于视图

user_list = User.objects.prefetch_related('users')

错误:

  

CharField不受支持的查找“类型”,或者在字段中不加入   允许

1 个答案:

答案 0 :(得分:0)

您可以使用双下划线访问type属性:

class UserFilter(django_filters.FilterSet):
    type = django_filters.ChoiceFilter(
        field_name='attribute_set__type', choices=Attribute.rolechoice
    )
    ...

type添加到Meta的字段列表中:

class Meta:
    model = User
    fields = ['userid', 'name', 'email', 'attributes', 'type']

您也可以只写:

    fields = '__all__'

如您所见,此语法类似于Django的ORM语法;已记录在here中。如果要更改字段的标签,可以使用附加的label参数来完成:

    type = django_filters.ChoiceFilter(
        field_name='attribute_set__type', choices=Attribute.rolechoice, label='User role'
    )

here中的更多ChoiceField详细信息。

此外,您可以考虑在视图中获取用户属性以及User中的queryset对象:

    user_list = User.objects.prefetch_related('attribute_set')

详细了解prefetch_related及其在the docs中的作用。