我需要(在后台)向django过滤器请求添加一个额外的过滤器属性。
我的型号:
class Event(models.Model):
name=models.CharField(max_length=254)
location=models.ForeignKey(Place)
invited_user=models.ManyToManyField(User,null=True, blank=True)
使用过滤器可以过滤那些具有相同位置的条目。这是有效的。
此外,我必须排除invited_user不是request.user的所有条目(只有在用户具有权限的情况下才能选择此筛选器属性)。
使用django过滤器可以做到这一点吗?如果可以,怎么做?
我的筛选器类:导入django_filter从模型导入事件
class EventFilter(django_filters.FilterSet):
class Meta:
model = Event
fields = ['location']
我的工作基于:如何使用Django通用视图过滤表?
您可以访问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
文档https://rpkilby.github.io/django-filter/guide/usage.html#filtering-主qs
我认为在您的情况下,您可以通过修改视图中的查询集来实现这一点,在那里您应该能够访问request.user。因此,您不需要深入研究django过滤器,
在我的例子中,当使用dango_filters FilterView和crispy表单来呈现表单时,我想从表单中隐藏字段,以及您所描述的额外过滤,所以我重写了FilterView的get(),将查询集限制为用户,并使用crispy窗体的布局编辑从过滤器表单中弹出不需要的字段:
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)
试试这个:
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