django-filter:使用request.user扩展过滤器查询

时间:2014-08-31 20:42:42

标签: django django-models filter django-tables2 django-filter

我需要在django-filter请求中添加额外的过滤器属性(在后台)。

我的模特:

class Event(models.Model):
  name=models.CharField(max_length=254)
  location=models.ForeignKey(Place)
  invited_user=models.ManyToManyField(User,null=True, blank=True)

使用过滤器可以过滤具有相同位置的条目。这很有效。

此外,我必须排除invite_user不是request.user的所有条目(仅当用户具有权限时才可以选择此过滤器属性)。

django-filter是否可以,如果是,怎么办?

我的过滤器类: import django_filters 来自模型导入事件

class EventFilter(django_filters.FilterSet):
    class Meta:
        model = Event
        fields = ['location']

我的工作基于:How do I filter tables with Django generic views?

3 个答案:

答案 0 :(得分:2)

试试这个:

class EventListView(BaseFilterView):
    ...
    def get_filterset(self, *args, **kwargs):
        fs = super().get_filterset(*args, **kwargs)
        fs.filters['location'].field.queryset = fs.filters['location'].field.queryset.filter(user=self.request.user)
        return fs

答案 1 :(得分:1)

您可以在FilterSet.qs属性中访问请求对象。

class EventFilter(django_filters.FilterSet):
class Meta:
    model = Event
    fields = ['location']

    @property
    def qs(self):
            queryset=super(EventFilter, self).qs
            if request.user.has_perm("app_label.has_permission"):       
                    return queryset.exclude(invited_user!=self.request.user)
            return queryset      

答案 2 :(得分:0)

我认为在您的情况下,您可以通过修改视图中的查询集来实现,您应该能够访问request.user。因此,您不需要深入研究django-filter,

在我的情况下,当使用dango_filters FilterView以及crispy表单来呈现表单时,我想隐藏表单中的字段,以及您所描述的其他过滤,所以我覆盖了FilterView的get(),限制了查询集给用户,并使用crispy form的布局编辑从过滤器表单中弹出不需要的字段:

def get(self, request, *args, **kwargs):
    """
    original code from django-filters.views.BaseFilterView - added admin check
    """
    filterset_class = self.get_filterset_class()
    self.filterset = self.get_filterset(filterset_class)
    self.object_list = self.filterset.qs
    # If not admin, restrict to assessor's own centre and clients
    if not request.user.get_profile().is_admin:
        self.object_list = self.object_list.filter(attendee__assessor=request.user)
        self.filterset.form.helper.layout[0].pop(2)  # centres filter
        self.filterset.form.helper.layout[0].pop(1)  # assessors filter
    context = self.get_context_data(filter=self.filterset,
                                    object_list=self.object_list)
    return self.render_to_response(context)